Newer
Older
intelligentRobot / src / views / dashboard / index.vue
wangxitong on 3 Sep 20 KB first commit
<script lang="ts" setup name="videoControl">
import type { FormInstance, FormRules } from 'element-plus'
import { ElMessage, ElMessageBox } from 'element-plus'
import type { Ref } from 'vue'
import { getCurrentInstance, reactive, ref } from 'vue'
import dayjs from 'dayjs'
import LineChart from '@/components/Echart/LineChart.vue'
import useWebsocketStore from '@/store/modules/websocket'
import { initPlugin, login, logout, onlyLogin, preview } from '@/utils/HKVideo'
import controlImg from '@/assets/images/control.png'
import type { lineDataI } from '@/components/Echart/echart-interface'
import { delAlarm, getAlarmListPage } from '@/api/ptz/alarm'
import { getDataHisList, getDevInfo, restartDev } from '@/api/ptz/dev'
import ThreeMap from '@/components/ThreeMap/index.vue'
import {getRobotList, robotDetail, robotFour} from "@/api/home/robot/robot";
import useSettingsStore from "@/store/modules/settings";
import {ptzFour} from "@/api/home/robot/ptz";
import {getDevList, hsList} from "@/api/home/tcy/tcy"; // 竖轴

const threeMap = ref() // 组件
const settingsStore = useSettingsStore()
// const mapSize = ref(260)
// const mapNum = ref(20)
const gridHeight = ref(200)
const gridWidth = ref(200)
const resolution = ref(4)
const pcdUrl = ref('')
const websocket = useWebsocketStore()
const $route = useRoute()
const wiper = ref(true)
const realppm = ref('****')
const xinput = ref('0')
const jinput = ref('0')
const realh = ref('****')
const realv = ref('****')
const clickType = ref(true)
const devCH4XData: Ref<string[]> = ref([])
const devCH4Data: Ref<lineDataI[]> = ref([{name: '检测数值', data: []}])

const tableData = ref([])
const instance = getCurrentInstance()
const selectPoint = ref('')
// control
const robotRun = ref({w: 0, v: 0, isStop: true})
const timer = ref()
const wv = ref({w: 0, v: 0})
const divPlugin = ref(null)
const lineList: Ref<any[]> = ref([])
const pointList: Ref<any[]> = ref([])

const addData = ref({
  speed: '',
  time: '',
  alarm: '',
})
const activeName= ref('0')
const pointName = ref('')
const showAdd = ref(false)

const x1 = ref(0)
const x2 = ref(4095)
const x3 = ref(0)
const x4 = ref(4095)

const mcaData: Ref<any[]> = ref([
  {name: 'mca', data:  []},
  {name: '', data: []}
])
const psdData: Ref<any[]> = ref([
  {name: 'psd', data:  []},
  {name: '', data: []}
])

let mcaobj0 = {}
let mcaobj1 = {}
let psdobj0 = {}
let psdobj1 = {}

// socket更新数据

// socket更新数据
const unwatch = watch(websocket, (newVal) => {
  if (newVal.psdData && Object.keys(newVal.psdData).length >= 1 && settingsStore.robot.id === newVal.psdData.robotId ) {
    // 判断折现数据长度
    if (devCH4XData.value.length > 300) {
      devCH4XData.value.splice(0, 100)
      devCH4Data.value[0].data.splice(0, 100)
    }
    devCH4XData.value = [...devCH4XData.value, newVal.psdData.time]
    devCH4Data.value = [{name: '检测数值', data: devCH4Data.value[0].data.concat(newVal.psdData.psd)}]
  } else if (newVal.alarmData && Object.keys(newVal.alarmData).length >= 1 ) {
    newVal.alarmData.position = newVal.alarmData.x + ',' + newVal.alarmData.y
    tableData.value.push(newVal.alarmData)
  } else if (newVal.detectorHData && Object.keys(newVal.detectorHData).length >= 1 ) {
    if(mcaobj0.hasOwnProperty(newVal.detectorHData.mcaX)) {
      mcaobj0[newVal.detectorHData.mcaX] += newVal.detectorHData.mcaY
    } else {
      mcaobj0[newVal.detectorHData.mcaX] = newVal.detectorHData.mcaY
    }
    if(mcaobj1.hasOwnProperty(newVal.detectorHData.mcaX1)) {
      mcaobj1[newVal.detectorHData.mcaX1] += newVal.detectorHData.mcaY1
    } else {
      mcaobj1[newVal.detectorHData.mcaX1] = newVal.detectorHData.mcaY1
    }

    if(psdobj0.hasOwnProperty(newVal.detectorHData.psdX)) {
      psdobj0[newVal.detectorHData.psdX] += newVal.detectorHData.psdY
    } else {
      psdobj0[newVal.detectorHData.psdX] = newVal.detectorHData.psdY
    }
    if(psdobj1.hasOwnProperty(newVal.detectorHData.psdX1)) {
      psdobj1[newVal.detectorHData.psdX1] += newVal.detectorHData.psdY1
    } else {
      psdobj1[newVal.detectorHData.psdX1] = newVal.detectorHData.psdY1
    }
  }
})

// 云台上下左右
function controlWithSpeed( type: any, isStop: any) {
  // console.log(type)
  const params = {
    deviceIp: settingsStore.robot.ptzInfo.deviceIp,
    robotId: settingsStore.robot.id,
    command: type,
    isStop,
    // speed: controlSpeed.value.toString(),
  }
  ptzFour(params).then(() => {})
}

const ptzClick = ref({
  up: 0,
  down: 0,
  left: 0,
  right: 0,
})
function controlWithSpeedClick(type: string) {
  if(type === 'up' || type === 'down' || type === 'left' || type === 'right' ) {
    ptzClick.value[type] = (ptzClick.value[type] + 1) % 2
    const params = {
      deviceIp: settingsStore.robot.ptzInfo?.deviceIp,
      robotId: settingsStore.robot.id,
      command: type,
      isStop : ptzClick.value[type],
      // speed: controlSpeed.value.toString(),
    }
    ptzFour(params).then(() => {})
  }
}

function getWV() {
  robotDetail({
    id: settingsStore.robot.id,
  }).then((res) => {
    if(res.code === 200) {
      wv.value.w = res.data.robotW
      wv.value.v = res.data.robotV
    }
  })
}

// 调整大小
const resize = () => {
  WebVideoCtrl.I_Resize(divPlugin.value.clientWidth, divPlugin.value.clientHeight)
}

function formatTooltip(val) {
  return `转动速度:${val}`
}

function tableRowClassName({ row, rowIndex }) {
  if (rowIndex % 2 === 1) {
    return 'e-row'
  }
  return ''
}

// 登录设备
function loginDevice() {
  login(
    settingsStore.robot.ptzInfo?.deviceIp,
    '80',
    settingsStore.robot.ptzInfo?.deviceUser,
    settingsStore.robot.ptzInfo?.devicePassword,
    0)
}

// 复位
function fw() {
  restartDev(settingsStore.robot.ptzInfo?.doorIp, settingsStore.robot.ptzInfo?.doorSn).then(() => {
    ElMessage.success('复位成功')
  })
}

const keydownRun = ref({
  w: false,
  a: false,
  s: false,
  d: false,
  ArrowUp: false,
  ArrowLeft: false,
  ArrowDown: false,
  ArrowRight: false
})
function keydown(event: { key: string }) {
  if (event.key === 'w' && !keydownRun.value[event.key]) {
    keydownRun.value[event.key] = true
    controlWithSpeed('up', 0)
  } else if (event.key === 'a' && !keydownRun.value[event.key]) {
    keydownRun.value[event.key] = true
    controlWithSpeed('left', 0)
  } else if (event.key === 's' && !keydownRun.value[event.key]) {
    keydownRun.value[event.key] = true
    controlWithSpeed('down', 0)
  } else if (event.key === 'd' && !keydownRun.value[event.key]) {
    keydownRun.value[event.key] = true
    controlWithSpeed('right', 0)
  } else if (event.key === 'ArrowUp' && !keydownRun.value[event.key]) {
    keydownRun.value[event.key] = true
    robotRun.value = {w: 0,v: wv.value.v, isStop: false}
  } else if (event.key === 'ArrowLeft' && !keydownRun.value[event.key]) {
    keydownRun.value[event.key] = true
    robotRun.value = {v: 0,w: wv.value.w, isStop: false}
  } else if (event.key === 'ArrowDown' && !keydownRun.value[event.key]) {
    keydownRun.value[event.key] = true
    robotRun.value = {w: 0,v: -wv.value.v, isStop: false}
  } else if (event.key === 'ArrowRight' && !keydownRun.value[event.key]) {
    keydownRun.value[event.key] = true
    robotRun.value = {v: 0,w: -wv.value.w, isStop: false}
  }
}

function keyup(event: { key: string }) {
  if (event.key === 'w') {
    keydownRun.value[event.key] = false
    controlWithSpeed('up', 1)
  } else if (event.key === 'a') {
    keydownRun.value[event.key] = false
    controlWithSpeed('left', 1)
  } else if (event.key === 's') {
    keydownRun.value[event.key] = false
    controlWithSpeed('down', 1)
  } else if (event.key === 'd') {
    keydownRun.value[event.key] = false
    controlWithSpeed('right', 1)
  } else if (event.key === 'ArrowUp') {
    keydownRun.value[event.key] = false
    robotRun.value = {w: 0,v: wv.value.v, isStop: true}
  } else if (event.key === 'ArrowLeft') {
    keydownRun.value[event.key] = false
    robotRun.value = {v: 0,w: wv.value.w, isStop: true}
  } else if (event.key === 'ArrowDown') {
    keydownRun.value[event.key] = false
    robotRun.value = {w: 0,v: -wv.value.v, isStop: true}
  } else if (event.key === 'ArrowRight') {
    keydownRun.value[event.key] = false
    robotRun.value = {v: 0,w: -wv.value.w, isStop: true}
  }
}

// 获取历史甲烷浓度
function getCH4() {
  const param = {
    monitorId: $route.query.id,
    startTime: dayjs(Date.now() - 1 * 60 * 1000).format('YYYY-MM-DD HH:mm:ss'),
    endTime: dayjs().format('YYYY-MM-DD HH:mm:ss'),
  }
  // 历史浓度
  getDataHisList(param).then((res) => {
    const yValue = res.data.reverse().map((item: any) => {
      if (Object.keys(item).toString().includes('num')) {
        Number(item.num)
      }
      else {
        Number(item.concentration)
      }
    })
    // devCH4YDataMax.value = Math.max(yValue) > 10 ? Math.max(yValue) : 10
    // devCH4XData.value = res.data.map((item: any) => item.logTime ? item.logTime.split(' ')[1] : '')
    // devCH4Data.value = [{ name: 'CH4', data: yValue }]
  })
}

onMounted(() => {
  setTimeout(() => {
    getRobotList({}).then((response) => {
      if(response.code === 200) {
        const robot = response.data.filter((item: any) => item.id === settingsStore.robot.id)[0]
        pcdUrl.value = window.localStorage.getItem('baseurl-robot') + '/static/finalCloud_' + robot.id + '.pcd'
        // mapSize.value = Number(robot.gridSize)
        // mapNum.value = Number(robot.gridNumber)
        gridHeight.value = Number(robot.gridHeight)
        gridWidth.value = Number(robot.gridWidth)
        resolution.value = Number(robot.resolution)
        setTimeout(() => {
          threeMap.value.initMap()
        }, 100)
        getWV()
      }
    })

    initPlugin(1, '', false, loginDevice, null)
    divPlugin.value = document.getElementById('divPlugin')
    // 机器人控制
    timer.value = setInterval(function() {
      if(robotRun.value.isStop) return
      const params = {
        action: 0,
        priority: 0,
        robotId: settingsStore.robot.id,
        w: robotRun.value.w,
        v: robotRun.value.v,
      }
      robotFour(params).then(() => {})
    }, 500); // 每隔0.5秒执行一次
    // 甲烷历史浓度
    // getCH4()
    window.addEventListener('resize', resize)
    // WASD ↑.←.↓.→
    document.addEventListener('keydown', keydown)
    document.addEventListener('keyup', keyup)

    updateTimer()
    getDevList({}).then((response) => {
      if(response.code === 200) {
        robot.value = response.data.filter((item: { robotId: any; }) => item.robotId === settingsStore.robot.id)[0]
        hs(1)
      }
    })
  }, 200)
})
const updateTimer = () => {
  mcaData.value[0].data = Object.entries(mcaobj0)
  mcaData.value[1].data = Object.entries(mcaobj1)
  psdData.value[0].data = Object.entries(psdobj0)
  psdData.value[1].data = Object.entries(psdobj1)
};

const timer1 = setInterval(updateTimer, 1000);
const robot = ref({})

function hs(type: any) {
  hsList({
    detectorId: robot.value.id,
    type,
    x1: x1.value,
    x2: x2.value,
    x3: x3.value,
    x4: x4.value,
  }).then((res) => {
    if(res.code === 200) {
      ElMessage.success('指令下发成功')
    }
  })
}


onBeforeUnmount(() => {
  // WebVideoCtrl.JS_HideWnd()
  WebVideoCtrl.I_Resize(0, 0)
  unwatch()
  logout(settingsStore.robot.ptzInfo?.deviceIp)
  timer.value && clearInterval(timer.value)
  timer1 && clearInterval(timer1)
  window.location.reload()
  window.removeEventListener('resize', resize)
  document.removeEventListener('keydown', keydown)
  document.removeEventListener('keyup', keyup)
})
</script>

<template>
  <div class="video-wrap">
    <div class="left-container">
      <three-map ref="threeMap" class="map-kzt" id="pcdcontainer-kzt" :gridHeight="gridHeight" :gridWidth="gridWidth" :resolution="resolution" :pcdUrl="pcdUrl"/>
      <el-table
        style="width: 100%;height: 200px;margin-top: 5px;"
        :data="tableData"
        :row-class-name="tableRowClassName"
        height="200"
        size="small"
        border>
        <el-table-column prop="robotName" label="设备名称" align="center" />
        <el-table-column prop="taskTypeName" label=任务类型 align="center" />
        <el-table-column prop="discernTypeName" label="识别类型" align="center" />
        <el-table-column prop="monitorVal" label="检测数值" align="center" />
        <el-table-column prop="position" label="告警位置" align="center" />
        <el-table-column prop="alarmTime" label="告警时间" align="center" />
      </el-table>
      <div style="width: 160px;color: #2a3746;font-family: 微软雅黑;font-size: 14px;position: absolute;right: 40%;bottom: 220px;z-index: 99999999;" v-if="activeName !== '0'">
        <div>X1:<el-input-number v-model="x1" :precision="0" :step="1" :min="0" :max="4095" size="small"/></div>
        <div style="margin-top: 6px">X2:<el-input-number v-model="x2" :precision="0" :step="1" :min="0" :max="4095" size="small"/></div>
        <div style="margin-top: 6px">X3:<el-input-number v-model="x3" :precision="0" :step="1" :min="0" :max="4095" size="small"/></div>
        <div style="margin-top: 6px">X4:<el-input-number v-model="x4" :precision="0" :step="1" :min="0" :max="4095" size="small"/></div>
      </div>
    </div>
    <div class="right-container">
      <div id="divPlugin" class="videoControl" />
      <el-tabs v-model="activeName" style="margin-left: 10px">
        <el-tab-pane label="检测数值" name="0"/>
        <el-tab-pane label="mca" name="mca"/>
        <el-tab-pane label="psd" name="psd"/>
      </el-tabs>
      <div class="ppm-line">
        <line-chart v-if="activeName==='0'" :x-axis-data="devCH4XData" width="100%" :data="devCH4Data" unit="" :grid="{ top: 10, left: 10, right: 10, bottom: 20, containLabel: true }" />
        <bar-chart-vertical v-if="activeName==='mca'" id="mca" width="100%" :isDataZoom="false" :data="mcaData" unit="" :grid="{ top: 10, left: 10, right: 10, bottom: 20, containLabel: true }" />
        <bar-chart-vertical v-if="activeName==='psd'" id="psd" width="100%" :isDataZoom="false" :data="psdData" unit="" :grid="{ top: 10, left: 10, right: 10, bottom: 20, containLabel: true }" />
      </div>
      <div class="bottom">
        <el-switch
          style="margin: 10px"
          v-model="clickType"
          active-text="连续"
          inactive-text="点动">
        </el-switch>
        <div style="margin-left: 10px;color: #4f4f4f;margin-bottom: 8px"><svg-icon name="icon-keyboard" style="width: 16px;height: 16px;margin-right: 8px"/>可由键盘控制</div>
        <div style="margin-left: 10px;font-weight: bolder;color: #555555;margin-bottom: 2px;font-size:14px">云&nbsp&nbsp&nbsp台: W.A.S.D</div>
        <div style="margin-left: 10px;font-weight: bolder;color: #555555;font-size:14px">机器人: ↑.←.↓.→</div>
        <div class="control-title" style="right: 360px">云台控制</div>
        <el-image style="width: 130px; height: 130px;position: absolute;bottom: 10px;right: 220px" :src="controlImg" fit="fill" />
<!--        <el-icon style="position: absolute;bottom: 62px;right: 272px;z-index: 1111111;color: #626262;font-size: 24px;font-weight: bold;cursor: pointer" title="复位" @click="fw"><Refresh/></el-icon>-->
        <div v-show="clickType">
          <div class="round-btn" style="bottom: 95px;right: 265px" @mousedown="controlWithSpeed('up', 0)" @mouseup="controlWithSpeed('up', 1)" />
          <div class="round-btn" style="bottom: 13px;right: 265px" @mousedown="controlWithSpeed('down', 0)" @mouseup="controlWithSpeed('down', 1)"/>
          <div class="round-btn" style="bottom: 53px;right: 223px" @mousedown="controlWithSpeed('right', 0)" @mouseup="controlWithSpeed('right', 1)"/>
          <div class="round-btn" style="bottom: 53px;right: 305px" @mousedown="controlWithSpeed('left', 0)" @mouseup="controlWithSpeed('left', 1)"/>
        </div>
        <div v-show="!clickType">
          <div class="round-btn" style="bottom: 95px;right: 265px" @click="controlWithSpeedClick('up')" />
          <div class="round-btn" style="bottom: 13px;right: 265px" @click="controlWithSpeedClick('down')"/>
          <div class="round-btn" style="bottom: 53px;right: 223px" @click="controlWithSpeedClick('right')"/>
          <div class="round-btn" style="bottom: 53px;right: 305px" @click="controlWithSpeedClick('left')"/>
        </div>
        <div class="control-title" style="right: 150px">机器人控制</div>
        <el-image style="width: 130px; height: 130px;position: absolute;bottom: 10px;right: 10px" :src="controlImg" fit="fill" />
        <div v-show="clickType">
          <div class="round-btn" style="bottom: 13px;right: 55px" @mousedown="robotRun={w: 0,v: -wv.v,isStop: false}" @mouseup="robotRun={w: 0,v: -wv.v,isStop: true}"/>
          <div class="round-btn" style="bottom: 95px;right: 55px" @mousedown="robotRun={w: 0,v: wv.v,isStop: false}" @mouseup="robotRun={w: 0,v: wv.v,isStop: true}"/>
          <div class="round-btn" style="bottom: 53px;right: 95px" @mousedown="robotRun={w: wv.w,v: 0,isStop: false}" @mouseup="robotRun={w: wv.w,v: 0,isStop: true}"/>
          <div class="round-btn" style="bottom: 53px;right: 13px" @mousedown="robotRun={w: -wv.w,v: 0,isStop: false}" @mouseup="robotRun={w: -wv.w,v: 0,isStop: true}"/>
        </div>
        <div v-show="!clickType">
          <div class="round-btn" style="bottom: 13px;right: 55px" @click="robotRun={w: 0,v: -wv.v,isStop: !robotRun.isStop}"/>
          <div class="round-btn" style="bottom: 95px;right: 55px" @click="robotRun={w: 0,v: wv.v,isStop: !robotRun.isStop}"/>
          <div class="round-btn" style="bottom: 53px;right: 95px" @click="robotRun={w: wv.w,v: 0,isStop: !robotRun.isStop}"/>
          <div class="round-btn" style="bottom: 53px;right: 13px" @click="robotRun={w: -wv.w,v: 0,isStop: !robotRun.isStop}"/>
        </div>
      </div>
    </div>
  </div>
</template>

<style lang="scss" >
.el-table .e-row {
  background: #f0f4fe;
}
</style>

<style lang="scss" scoped>
.map-kzt {
  width: 100%;
  height: calc(100% - 205px);
}
.video-wrap {
  width: 100%;
  height: calc(100vh - 60px);
  display: flex;
  flex-wrap: wrap;
  background: white;
}
.left-container {
  width: calc(60% - 15px);
  height: calc(100% - 10px);
  border-radius: 10px;
  margin: 5px;
}
.right-container {
  width: 40%;
  height: calc(100% - 10px);
  border-radius: 10px;
  margin: 5px 0px;
}
.ppm-line {
  width: calc(100% - 0px);
  height: calc(55% - 185px);
  margin-top: -10px;
  flex: 1;
}
.videoControl {
  //float: right;
  height: 45%;
  width: 100%;
  //position: relative;
}
.bottom {
  width: 100%;
  height: 135px;
  background: #eef2fd;
  border-radius: 10px;
}
.box-card {
  width: 100%;
  height: calc(50% - 5px);
  margin-bottom: 5px;
  padding: 5px !important;
  box-shadow: 0 2px 12px 0 rgba(0,0,0,.1);
  overflow: hidden;
}
.control-title {
  color: white;
  background-color: #ff9f11;
  border-bottom-right-radius: 10px;
  border-top-right-radius: 10px;
  writing-mode: vertical-rl;
  text-orientation: upright;
  width: 30px;
  height: 100px;
  line-height: 30px;
  font-weight: bold;
  text-align: center;
  letter-spacing: 1px;
  position: absolute;
  bottom: 40px;
  font-family: Helvetica Neue,Helvetica,PingFang SC,Hiragino Sans GB,Microsoft YaHei,SimSun,sans-serif;
}
.set-btn {
  margin-left: 10px;
  width: 80px;
}

.btn-contain {
  margin-left: 10%;
  width: 55%;
  display: flex;
  flex-wrap: wrap;
  align-content: space-around;
  justify-content: center;
}
.btn {
  width: 20%;
  height: 40px;
  font-size: 16px;
}
.data-monitor {
  margin: 0px 5px;
  color: #a6cbff;
  font-weight: bold;
  letter-spacing: 1px;
  padding: 5px;
  width: 44%;
  h {
    padding-left: 10px;
    color: white;
    font-weight: normal;
    font-size: 16px;
  }
}
.el-message-box {
  position: absolute !important;
  top: calc(50% - 68px) !important;
  left: 100px !important;
}
.ptz-control {
  width: 400px;
  position: absolute;
  right: 18%;
  top: 5px;
  display: flex;
  justify-content: center;
  align-items: flex-start;
  flex-wrap: wrap;
}
.round-btn {
  position: absolute;
  width: 42px;
  height: 42px;
  z-index: 111111;
  border-radius: 21px;
  cursor: pointer;
}
.round-btn:hover {
  background-color: rgba(61, 125, 254, 0.53);
}
.icon-button {
  background-color: #d6e5fc;
  border-color: #d6e5fc;
  padding: 6px;
  border-radius: 6px;
  color: #4384ff;

  :deep(.el-icon) {
    width: 18px;
    height: 18px;
  }

  &:hover {
    background-color: #c3dafd;
    color: #fff;
  }
}
</style>