提交 6968109d 作者: 翁进城

feat: MMCMount

上级 6b238d6e
......@@ -13,6 +13,7 @@ import MMCMQTT from './src/plugins/MMCMQTT';
import MMCGroundStation from "./src/plugins/MMCGroundStation";
import MMCFlightControlCenter from './src/components/MMCFlightControlCenter';
import MMCFlightControlCenterPlugin from './src/components/MMCFlightControlCenter/plugin';
import MMCMount from './src/components/MMCMount';
// import MMCFlightControlCenter from './dist';
import SymbolIcon from './src/components/symbol-icon';
......@@ -43,4 +44,5 @@ export default {
...plugins
};
export { default as MMCFlightControlCenterMain } from './src/components/MMCFlightControlCenter/main';
\ No newline at end of file
export { default as MMCFlightControlCenterMain } from './src/components/MMCFlightControlCenter/main';
export { default as MMCMount } from './src/components/MMCMount';
\ No newline at end of file
<template>
<div class="cpt-MMC_Gimbal_FB1" :style="containerStyle" v-interact>
<div class="hd">
<div class="left ml8">
<img src="../assets/images/mount/mount_head.png" />
<div class="title">破窗灭火器</div>
</div>
<div class="close" @click="$emit('close')">关闭</div>
</div>
<div class="bd">
<img src="../assets/images/observe/010.svg" alt />
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险:</div>
<div class="input-box">
<el-switch
v-model="safety_switch_state"
size="mini"
@change="handle_safety_switch_state"
/>
</div>
</div>
<div class="form-item mt16">
<div class="label-box">开关:</div>
<div class="input-box">
<el-switch v-model="laser_shine_ctrl" size="mini" @change="handle_laser_shine_ctrl" />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_FB1 } from '../utils';
export default {
props: {
containerStyle: {
type: Object,
default: () => ({})
}
},
data() {
return {
timer: null,
radio: 1,
safety_switch_state: true,
laser_shine_ctrl: false
};
},
mounted() {},
methods: {
handle_laser_shine_ctrl() {
if (this.safety_switch_state) {
this.$message.warning('请关闭保险');
this.laser_shine_ctrl = false;
} else {
const buff = MMC_Gimbal_FB1.laser_shine_ctrl(Number(this.laser_shine_ctrl));
this.commit_directive(buff);
if (this.laser_shine_ctrl) {
this.$message.success('已打开');
}
// this.safety_switch_state = !this.safety_switch_state
}
},
handle_safety_switch_state() {
if (this.safety_switch_state) {
const buff = MMC_Gimbal_FB1.laser_shine_ctrl(0);
this.commit_directive(buff);
this.laser_shine_ctrl = false;
}
},
commit_directive(buffer) {
// console.log(buffer);
this.$emit('directive', buffer);
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_FB1 {
position: absolute;
// bottom: 0;
right: 0;
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
width: 280px;
// height: 218px;
box-sizing: border-box;
.hd {
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(16, 65, 215, 0.2);
box-shadow: inset 0 0 15px 0 rgba(0, 182, 255, 0.6);
border-radius: 10px 10px 0 0;
.left {
display: flex;
align-items: center;
.title {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.close {
font-size: 14px;
font-family: MicrosoftYaHei;
color: #d2dfff;
margin-right: 8px;
cursor: pointer;
}
}
.bd {
display: flex;
.form-wrap {
padding: 16px 0;
width: 100%;
height: 100px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
.form-item {
display: flex;
align-items: center;
.label-box {
color: #cbd0eb;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
.launch {
margin-left: 16px;
display: flex;
flex-direction: column;
align-items: center;
}
}
}
}
</style>
<template>
<div class="cpt-MMC_Gimbal_FN3" :style="containerStyle" v-interact>
<div class="hd">
<div class="left ml8">
<img src="../assets/images/mount/mount_head.png" />
<div class="title">网枪</div>
</div>
<div class="close" @click="$emit('close')">关闭</div>
</div>
<div class="bd">
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险:</div>
<div class="input-box">
<el-switch v-model="safety_switch_state" size="mini" />
</div>
</div>
<div class="form-item mt16">
<img src="../assets/images/observe/011.svg" alt="" />
<div class="launch">
<img src="../assets/images/mount/launch.png" alt="" @click="handle_laser_shine_ctrl" />
<div class="label-box">发射</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_FN3 } from '../utils';
export default {
props: {
containerStyle: {
type: Object,
default: () => ({})
}
},
data() {
return {
timer: null,
radio: 1,
safety_switch_state: true
};
},
mounted() {},
methods: {
handle_laser_shine_ctrl(value) {
if (this.safety_switch_state) {
this.$message.warning('请关闭保险');
} else {
const buff = MMC_Gimbal_FN3.laser_shine_ctrl(1);
this.commit_directive(buff);
this.$message.success('发射成功');
this.safety_switch_state = !this.safety_switch_state;
}
},
commit_directive(buffer) {
// console.log(buffer);
this.$emit('directive', buffer);
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_FN3 {
position: absolute;
// bottom: 0;
right: 0;
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
width: 240px;
// height: 218px;
box-sizing: border-box;
.hd {
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(16, 65, 215, 0.2);
box-shadow: inset 0 0 15px 0 rgba(0, 182, 255, 0.6);
border-radius: 10px 10px 0 0;
.left {
display: flex;
align-items: center;
.title {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.close {
font-size: 14px;
font-family: MicrosoftYaHei;
color: #d2dfff;
margin-right: 8px;
cursor: pointer;
}
}
.bd {
display: flex;
.form-wrap {
padding: 16px 0;
width: 100%;
height: 130px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
.form-item {
display: flex;
align-items: center;
.label-box {
color: #cbd0eb;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
.launch {
margin-left: 16px;
display: flex;
flex-direction: column;
align-items: center;
}
}
}
}
</style>
<template>
<div class="cpt-MMC_Gimbal_FE3" :style="containerStyle" v-interact>
<div class="hd">
<div class="left ml8">
<img src="../assets/images/mount/mount_head.png" />
<div class="title">干粉灭火器</div>
</div>
<div class="close" @click="$emit('close')">关闭</div>
</div>
<div class="bd">
<img class="ml16" src="../assets/images/observe/019.svg" alt="" />
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险</div>
<div class="input-box">
<el-switch v-model="safety_switch_state" size="mini" />
</div>
</div>
<div class="form-item">
<div class="label-box">开关</div>
<div class="input-box" @click="handle_fire_ctrl">
<el-switch v-model="fire_status" size="mini" />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_FE3 } from '../utils';
export default {
props: {
containerStyle: {
type: Object,
default: () => ({})
}
},
data() {
return {
radio: 1,
// 保险状态
safety_switch_state: false,
// 开关状态
fire_status: false
};
},
methods: {
handle_fire_ctrl() {
console.log(111, this.safety_switch_state);
if (!this.safety_switch_state) {
this.$message.warning('保险未打开!');
return (this.fire_status = false);
}
let buff = null;
if (this.fire_status) {
buff = MMC_Gimbal_FE3.gimbal_mode2_ctrl(1);
} else {
buff = MMC_Gimbal_FE3.gimbal_mode2_ctrl(0);
}
this.commit_directive(buff);
},
commit_directive(buffer) {
this.$emit('directive', buffer);
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_FE3 {
position: absolute;
// bottom: 0;
right: 0;
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
width: 280px;
// height: 218px;
box-sizing: border-box;
.hd {
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(16, 65, 215, 0.2);
box-shadow: inset 0 0 15px 0 rgba(0, 182, 255, 0.6);
border-radius: 10px 10px 0 0;
.left {
display: flex;
align-items: center;
.title {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.close {
font-size: 14px;
font-family: MicrosoftYaHei;
color: #d2dfff;
margin-right: 8px;
cursor: pointer;
}
}
.bd {
display: flex;
.form-wrap {
padding: 16px 0;
width: 100%;
height: 100px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
.form-item {
display: flex;
align-items: center;
.label-box {
color: #cbd0eb;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
.launch {
margin-left: 16px;
display: flex;
flex-direction: column;
align-items: center;
}
}
}
}
</style>
<template>
<div class="cpt-MMC_Gimbal_FE8" :style="containerStyle" v-interact>
<div class="hd">
<!-- <div class="title">八孔投弹器</div> -->
<div class="left ml8">
<img src="../assets/images/mount/mount_head.png" />
<div class="title">催泪弹</div>
</div>
<div class="close" @click="$emit('close'), $emit('showCenter', false)">关闭</div>
</div>
<div class="bd">
<div class="rocker-wrap">
<div class="title-box">
<!-- <div class="title">操作</div> -->
</div>
<div ref="rocker" class="rocker">
<div class="shangUp" @click="fangxiang('up')" />
<div class="xaiUp" @click="fangxiang('down')" />
<div class="zuoUp" @click="fangxiang('right')" />
<div class="youUp" @click="fangxiang('left')" />
</div>
</div>
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险:</div>
<div class="input-box">
<el-switch v-model="safety_switch_state" size="mini" />
</div>
</div>
<div class="form-item launch">
<img src="../assets/images/mount/launch.png" alt="" @click="handle_laser_shine_ctrl" />
<div class="label-box">发射</div>
<!--<div class="input-box" @click="handle_laser_shine_ctrl">
<el-switch v-model="laser_shine_status" size="mini"></el-switch>
</div> -->
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_FE8 } from '../utils';
export default {
props: {
containerStyle: {
type: Object,
default: () => ({})
}
},
data() {
return {
timer: null,
radio: 1,
safety_switch_state: false,
laser_shine_status: false
};
},
mounted() {
this.$emit('showCenter', true);
this.$nextTick(() => {
this.init_rocker();
});
},
methods: {
handle_laser_shine_ctrl(value) {
if (!this.safety_switch_state) {
this.$message.warning('未打开保险');
return (this.laser_shine_status = false);
} else {
// if (this.laser_shine_status) {
const buff = MMC_Gimbal_FE8.laser_shine_ctrl(1);
this.commit_directive(buff);
this.$message.success('发射成功');
// setTimeout(() => {
// this.laser_shine_status = false;
// }, 500);
// }
}
},
commit_directive(buffer) {
// console.log(buffer);
this.$emit('directive', buffer);
},
fangxiang(type) {
let buffer = null;
switch (type) {
case 'up':
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
break;
case 'right':
// buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
// this.commit_directive(buffer);
// setTimeout(() => {
// buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(-1);
// this.commit_directive(buffer);
// }, 50);
break;
case 'left':
// buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
// this.commit_directive(buffer);
// setTimeout(() => {
// buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(1);
// this.commit_directive(buffer);
// }, 50);
break;
case 'down':
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
}
this.timer = setTimeout(() => {
clearTimeout(this.timer);
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
}, 500);
},
init_rocker() {
let buffer = null;
joystick({
// zone: this.$refs["rocker"],
// mode: "static",
// position: { left: "50%", top: "50%" },
// color: "#9bacbe",
onstart: (type) => {
switch (type) {
case 'up':
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
break;
case 'right':
// buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
// this.commit_directive(buffer);
// setTimeout(() => {
// buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(-1);
// this.commit_directive(buffer);
// }, 50);
break;
case 'left':
// buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
// this.commit_directive(buffer);
// setTimeout(() => {
// buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(1);
// this.commit_directive(buffer);
// }, 50);
break;
case 'down':
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
}
},
onend: () => {
buffer = MMC_Gimbal_FE8.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
}
});
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_FE8 {
position: absolute;
// bottom: 0;
right: 0;
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
width: 470px;
height: 290px;
box-sizing: border-box;
.hd {
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(16, 65, 215, 0.2);
box-shadow: inset 0 0 15px 0 rgba(0, 182, 255, 0.6);
border-radius: 10px 10px 0 0;
.left {
display: flex;
align-items: center;
.title {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.close {
font-size: 14px;
font-family: MicrosoftYaHei;
color: #d2dfff;
margin-right: 8px;
cursor: pointer;
}
}
.bd {
padding: 10px 20px;
display: flex;
// justify-content: space-between;
overflow-y: auto;
height: 230px;
overflow-x: hidden;
.form-wrap {
margin-left: 124px;
// min-width: 300px;
// flex-shrink: 0;
.form-item {
display: flex;
align-items: center;
height: 40px;
.label-box {
color: #cbd0eb;
// width: 75px;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
.launch {
margin-top: 35px;
margin-left: 22px;
display: flex;
flex-direction: column;
}
}
.rocker-wrap {
// flex: 1;
.title-box {
.title {
color: #cbd0eb;
}
}
.rocker {
// margin: 10px auto 0;
width: 150px;
height: 150px;
position: relative;
// margin: 0 auto;
background: center url('../assets/images/accident/caozuo.png') no-repeat;
background-size: 100% 100%;
.shangUp {
position: absolute;
left: 37%;
top: 4px;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.xaiUp {
position: absolute;
left: 37%;
bottom: 4px;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.zuoUp {
position: absolute;
left: 4px;
top: 37%;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.youUp {
position: absolute;
right: 4px;
top: 37%;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
}
}
}
}
::v-deep {
.el-select {
width: 165px;
margin-right: 5px;
.el-input {
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
}
.el-input {
width: 165px;
margin-right: 5px;
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
.el-radio-group {
.el-radio {
.el-radio__input {
&.is-checked {
.el-radio__inner {
border-color: #08c2d1;
background: #08c2d1;
}
}
}
.el-radio__label {
color: #cbd0eb;
}
}
}
.el-button {
background: #2aefed;
color: #000;
border: none;
}
}
</style>
<template>
<div class="cpt-MMC_Gimbal_FF6" v-interact>
<div class="hd">
<div class="title">喷火器</div>
</div>
<div class="bd">
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险</div>
<div class="input-box">
<el-switch v-model="safety_switch_state" size="mini" />
</div>
</div>
<div class="form-item">
<div class="label-box">喷火</div>
<div class="input-box">
<el-switch v-model="fire_status" size="mini" @change="handle_fire_ctrl" />
</div>
</div>
</div>
<div class="rocker-wrap">
<div class="title-box">
<div class="title">操作</div>
</div>
<div ref="rocker" class="rocker">
<div class="shangUp" @click="fangxiang('up')" />
<div class="xaiUp" @click="fangxiang('down')" />
<div class="zuoUp" @click="fangxiang('right')" />
<div class="youUp" @click="fangxiang('left')" />
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_FF6 } from '../utils';
export default {
data() {
return {
timer: null,
radio: 1,
safety_switch_state: false,
fire_status: false
};
},
mounted() {
this.$nextTick(() => {
this.init_rocker();
});
},
methods: {
handle_fire_ctrl(value) {
if (!this.safety_switch_state) {
return (this.fire_status = false);
}
const buff = MMC_Gimbal_FF6.fire_ctrl(1);
this.commit_directive(buff);
},
commit_directive(buffer) {
this.$emit('directive', buffer);
},
fangxiang(type) {
let buffer = null;
switch (type) {
case 'up':
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
}, 50);
break;
case 'right':
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(-1);
this.commit_directive(buffer);
}, 50);
break;
case 'left':
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(1);
this.commit_directive(buffer);
}, 50);
break;
case 'down':
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
}, 50);
}
this.timer = setTimeout(() => {
clearTimeout(this.timer);
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
}, 500);
},
init_rocker() {
let buffer = null;
joystick({
// zone: this.$refs["rocker"],
// mode: "static",
// position: { left: "50%", top: "50%" },
// color: "#9bacbe",
onstart: (type) => {
switch (type) {
case 'up':
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
}, 50);
break;
case 'right':
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(-1);
this.commit_directive(buffer);
}, 50);
break;
case 'left':
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(1);
this.commit_directive(buffer);
}, 50);
break;
case 'down':
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
setTimeout(() => {
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
}, 50);
}
},
onend: () => {
buffer = MMC_Gimbal_FF6.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
buffer = MMC_Gimbal_FF6.gimbal_yaw_ctrl(0);
this.commit_directive(buffer);
}
});
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_FF6 {
position: absolute;
top: 0px;
right: 0;
/* background: center url("../assets/images/observe/fckernel/mount/01_bg.png")
no-repeat; */
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
background-size: 100% 100%;
width: 500px;
height: 290px;
box-sizing: border-box;
padding: 10px 20px;
.hd {
.title {
font-size: 18px;
color: #08c2d1;
font-weight: bold;
line-height: 2;
}
}
.bd {
display: flex;
justify-content: space-between;
.form-wrap {
min-width: 245px;
flex-shrink: 0;
.form-item {
display: flex;
align-items: center;
height: 40px;
.label-box {
color: #cbd0eb;
width: 75px;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
}
.rocker-wrap {
flex: 1;
.title-box {
.title {
color: #cbd0eb;
}
}
.rocker {
margin: 10px auto 0;
width: 150px;
height: 150px;
position: relative;
margin: 0 auto;
background: center url('../assets/images/accident/caozuo.png') no-repeat;
background-size: 100% 100%;
.shangUp {
position: absolute;
left: 37%;
top: 4px;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.xaiUp {
position: absolute;
left: 37%;
bottom: 4px;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.zuoUp {
position: absolute;
left: 4px;
top: 37%;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
.youUp {
position: absolute;
right: 4px;
top: 37%;
border-radius: 50%;
width: 40px;
height: 40px;
border: 0px solid red;
cursor: pointer;
}
}
}
}
}
::v-deep {
.el-select {
width: 165px;
margin-right: 5px;
.el-input {
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
}
.el-input {
width: 165px;
margin-right: 5px;
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
.el-radio-group {
.el-radio {
.el-radio__input {
&.is-checked {
.el-radio__inner {
border-color: #08c2d1;
background: #08c2d1;
}
}
}
.el-radio__label {
color: #cbd0eb;
}
}
}
.el-button {
background: #2aefed;
color: #000;
border: none;
}
}
</style>
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn', 'co')">
<span class="pa top7 left-60 tc cf cp" style="z-index: 999">
<div>CO</div>
(ppm)
</span>
<div ref="CoChart" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value && value.toFixed(2) }}</div>
</div>
</template>
<script>
import echarts from 'echarts';
export default {
name: "C0Chart",
data() {
return {
chart: null,
value: 0,
option: {
grid: {
top: "40%",
height: "40%",
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false,
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false,
splitLine: {
show: false,
},
},
series: [
{
name: "CO",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
};
},
props: {
airData: {
type: String | Number,
default: 0,
},
},
mounted() {
this.initChart();
this.time = setInterval(() => {
if (this.airData >= 0) {
this.updateData(this.airData);
}
}, 1000);
},
methods: {
initChart() {
console.log(echarts, "echarts");
this.chart = echarts.init(this.$refs.CoChart);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date().getTime();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
}
</style>
<template>
<div class="chart-container-box ml55 pr cp" @click="$emit('fn','no2')">
<span class="pa cp top20 left-60 tc cf" style="z-index:999">
<div>NO2</div>(ppm)
</span>
<div ref="NO2" class="chart w299 h73"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
import echarts from 'echarts';
export default {
name: "NO2",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#fc9f00"],
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "NO2",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time:null
};
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
beforeDestroy(){
clearInterval(this.time)
},
mounted() {
this.initChart();
this.time= setInterval(() => {
if(this.airData>=0){
this.updateData( this.airData);
}
}, 1000);
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.NO2);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn','ox')">
<span class="pa top20 left-64 tc cp cf" style="z-index:999">
<div>Ox</div>(ppm)
</span>
<div ref="Ox" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
import echarts from 'echarts';
export default {
name: "Ox",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#1fca21"],
// title: {
// text: '动态数据',
// left: 'left', // 设置标题位置为左侧中间
// textAlign: 'center', // 设置标题在左侧居中显示
// // 其他选项...
// },
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "Ox",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time:null
};
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
mounted() {
this.initChart();
this.time= setInterval(() => {
if(this.airData>=0){
this.updateData(this.airData);
}
}, 1000);
},
beforeDestroy(){
clearInterval(this.time)
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.Ox);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn','pm1dot0')">
<span class="pa cp top20 left-64 tc cf" style="z-index:999">
<div>PM1.0</div>(ug/m3)
</span>
<div ref="PM" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
import echarts from 'echarts';
export default {
name: "PM",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#00a3da"],
// title: {
// text: '动态数据',
// left: 'left', // 设置标题位置为左侧中间
// textAlign: 'center', // 设置标题在左侧居中显示
// // 其他选项...
// },
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "PM1.0",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time:null
};
},
mounted() {
this.initChart();
this.time= setInterval(() => {
if(this.airData>=0){
this.updateData(this.airData);
}
}, 1000);
},
beforeDestroy(){
clearInterval(this.time)
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.PM);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn','pm10')">
<span class="pa top20 left-64 tc cf cp" style="z-index:999">
<div>PM10</div>(ug/m3)
</span>
<div ref="PM10" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
import echarts from 'echarts';
export default {
name: "PM10",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#1fca21"],
// title: {
// text: '动态数据',
// left: 'left', // 设置标题位置为左侧中间
// textAlign: 'center', // 设置标题在左侧居中显示
// // 其他选项...
// },
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "PM10",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time: null,
};
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
mounted() {
this.initChart();
this.time = setInterval(() => {
if (this.airData >= 0) {
this.updateData(this.airData);
}
}, 1000);
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.PM10);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn','pm2dot5')">
<span class="pa cp top20 left-64 tc cf" style="z-index:999">
<div>PM2.5</div>(ug/m3)
</span>
<div ref="PM2" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
import echarts from 'echarts';
export default {
name: "PM2",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#f63832"],
// title: {
// text: '动态数据',
// left: 'left', // 设置标题位置为左侧中间
// textAlign: 'center', // 设置标题在左侧居中显示
// // 其他选项...
// },
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "PM2.5",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time:null
};
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
mounted() {
this.initChart();
this.time= setInterval(() => {
if(this.airData>=0){
this.updateData(this.airData);
}
}, 1000);
},
beforeDestroy(){
clearInterval(this.time)
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.PM2);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
<template>
<div class="chart-container-box ml55 pr" @click="$emit('fn','so2')">
<span class="pa cp top20 left-64 tc cf" style="z-index:999">
<div>SO2</div>(ppm)
</span>
<div ref="SO2" class="chart w299 h65"></div>
<div class="pa right8 cf tc top8">{{ value&&value.toFixed(2) }}</div>
</div>
</template>
<script>
import echarts from 'echarts';
export default {
name: "SO2",
data() {
return {
chart: null,
value: 0,
option: {
color: ["#1fca21"],
// title: {
// text: '动态数据',
// left: 'left', // 设置标题位置为左侧中间
// textAlign: 'center', // 设置标题在左侧居中显示
// // 其他选项...
// },
grid: {
top: "40%",
height: "40%", // 调整 grid 的 height 值,缩小图表的高度
borderWidth: 1,
borderColor: "#294598",
},
backgroundColor: "#02173dc4",
tooltip: {
trigger: "axis",
axisPointer: {
animation: false,
},
},
xAxis: {
type: "time",
splitLine: {
show: false,
},
show: false, // 隐藏 Y 轴
},
yAxis: {
type: "value",
boundaryGap: [0, "100%"],
show: false, // 隐藏 Y 轴
splitLine: {
show: false,
},
},
series: [
{
name: "SO2",
type: "line",
showSymbol: false,
hoverAnimation: false,
data: [],
},
],
},
time:null
};
},
props: {
airData: {
type: String | Number,
default: () => 0,
},
},
mounted() {
this.initChart();
this.time= setInterval(() => {
if(this.airData>=0){
this.updateData(this.airData);
}
}, 1000);
},
beforeDestroy(){
clearInterval(this.time)
},
methods: {
initChart() {
this.chart = echarts.init(this.$refs.SO2);
this.chart.setOption(this.option);
},
updateData(value) {
const now = new Date();
this.value = value;
this.option.series[0].data.push([now, value]);
this.chart.setOption(this.option);
},
},
};
</script>
<style scoped lang="scss">
.chart-container-box {
width: 300px;
border: 1px solid #3bc1e5;
.chart {
height: 73px;
}
}
</style>
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
export default {
closeDialog() {
this.visible = false
this.warningInfor = {
title: "危险提示",
msg: 'Ox(ppm),大于0.1ppm对人体造成伤害(短期接触限值)'
}
},
// 计算颜色
color_from_value(num) {
if (parseInt(num) == 0) {
num = 0.1
}
let value = parseInt(num);
if (
this.taskSituation == "co" ||
this.taskSituation == "so2" ||
this.taskSituation == "ox"
) {
value = num / 5;
} else if (this.taskSituation == "no2") {
value = num * 2;
} else if (
this.taskSituation == "pm1dot0" ||
this.taskSituation == "pm2dot5" ||
this.taskSituation == "pm10"
) {
value = num / 2;
}
function interpolateColor(color1, color2, ratio) {
if (color1 && color2) {
let r1 = parseInt(color1.substr(1, 2), 16);
let g1 = parseInt(color1.substr(3, 2), 16);
let b1 = parseInt(color1.substr(5, 2), 16);
let r2 = parseInt(color2.substr(1, 2), 16);
let g2 = parseInt(color2.substr(3, 2), 16);
let b2 = parseInt(color2.substr(5, 2), 16);
let r = Math.round(r1 + (r2 - r1) * ratio);
let g = Math.round(g1 + (g2 - g1) * ratio);
let b = Math.round(b1 + (b2 - b1) * ratio);
let hex = "#" + (r < 16 ? "0" : "") + r.toString(16) + (g < 16 ? "0" : "") + g.toString(16) + (b < 16 ? "0" : "") + b.toString(16);
return hexToRgb(hex)
}
}
function hexToRgb(hex) {
hex = hex.replace("#", "");
let r = parseInt(hex.substr(0, 2), 16);
let g = parseInt(hex.substr(2, 2), 16);
let b = parseInt(hex.substr(4, 2), 16);
return Cesium.Color.fromBytes(r, g, b);
}
function getHexColor(number) {
if (number === 0) {
return "#47a447";
} else if (number === 100) {
return "#fb4747";
} else if (number >= 0 && number <= 100) {
// 计算相邻颜色的索引
let lowerIndex = Math.floor(number / 10);
let upperIndex = Math.ceil(number / 10);
// 根据索引获取相邻颜色
let lowerColor = getColorByIndex(lowerIndex);
let upperColor = getColorByIndex(upperIndex);
// 计算颜色之间的渐变比例
let ratio = (number - lowerIndex * 10) / 10;
if (!upperColor) {
upperColor = lowerColor
}
return interpolateColor(lowerColor, upperColor, ratio);
} else {
return "Invalid number. Please enter a number from 0 to 100.";
}
}
function getColorByIndex(index) {
let colors = [
"#47a447", "#47c147", "#47de47", "#4bfb47", "#88fb47", "#c5fb47", "#fbf847", "#fbc847", "#fb9a47", "#fb4747"
];
return colors[index];
}
// 示例用法
let inputNumber = value
let colorCode = getHexColor(inputNumber);
// 返回 RGB 颜色值
return colorCode
},
showLine(item) {
this.add_polylineNeW(window.viewer, this.lineCopy);
this.flyTo(window.viewer, this.positions);
},
Cartesian3_to_WGS84_Arr(point) {
let cartesian33 = new Cesium.Cartesian3(point.x, point.y, point.z);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian33);
let lat = Cesium.Math.toDegrees(cartographic.latitude);
let lng = Cesium.Math.toDegrees(cartographic.longitude);
let alt = cartographic.height;
return [lng, lat, alt]
},
add_polylineNeW(viewer, data) {
return viewer.entities.add({
polyline: {
positions: new Cesium.CallbackProperty(() => {
return this.lineCopy;
}, false),
width: 5,
material: Cesium.Color.fromCssColorString("#ff0000"),
show: true,
zIndex: 10,
},
});
},
addModel(viewer, position) {
return viewer.entities.add({
id: "nest_uav_model",
position: new Cesium.CallbackProperty(() => this.positions, false),
model: {
uri: "cesium/model/mmcModel2.gltf",
// color: Cesium.Color.fromAlpha(Cesium.Color.BLUE, parseFloat(0.8)), //模型颜色,透明度
minimumPixelSize: 50, //指定模型的近似最小像素大小(不考虑缩放)的数值属性
maximumScale: 10000, //模型的最大比例大小。最小像素化的上限
silhouetteSize: "", //轮廓大小
scale: 1,
disableDepthTestDistance: 50000,
//轮廓线
silhouetteColor: Cesium.Color.fromAlpha(
Cesium.Color.fromCssColorString("#4fafe3"),
parseFloat(0.5)
),
//模型样式 ['Highlight', 'Replace', 'Mix']
colorBlendMode: Cesium.ColorBlendMode.Highlight,
//colorBlendAmount需要选择mix后将colorBlendAmountEnabled设置为true才能使用
colorBlendAmountEnabled: true,
colorBlendAmount: parseFloat(0.8),
},
});
},
// dataFn() {
// let i = 0;
// this.lineCopy = [this.line[0]];
// setInterval(() => {
// if (i < this.line.length) {
// const item = this.line[i];
// const curPos = this.uavModel.position.getValue(
// Cesium.JulianDate.now()
// );
// const curCart = new Cesium.Cartesian3(curPos.x, curPos.y, curPos.z);
// const afterCart = new Cesium.Cartesian3(item.x, item.y, item.z);
// if (curCart.equals(afterCart)) {
// i++;
// return;
// }
// this.lineCopy.push(this.line[i]);
// this.positions = this.line[i];
// i++;
// }
// }, 50);
// },
}
\ No newline at end of file
import mqtt from "mqtt";
const {
VUE_APP_MQTT_URL
} = process.env;
export default {
initGasDetection(GasDetectionData) {
let {
longitude,
latitude
} = GasDetectionData
// 将经纬度转换为 Cartographic 坐标
const positionCartographic = Cesium.Cartographic.fromDegrees(longitude, latitude);
// 将 Cartographic 坐标转换为 Cartesian3 坐标
const positionCartesian = Cesium.Cartographic.toCartesian(positionCartographic);
let data = {
...GasDetectionData,
position: positionCartesian
}
this.gasDetectionObj = data
this.gasDetection.push(data)
},
uint8array2json(uint8array) {
if (!uint8array || !uint8array.length) {
return uint8array;
}
let {
decoder
} = this.mqtt;
if (!decoder) {
decoder = new TextDecoder("utf-8");
}
let content = decoder.decode(uint8array);
return content ? JSON.parse(content) : content;
},
json2uint8array(data) {
if (!data) {
return data;
}
let {
encoder
} = this.mqtt;
if (!encoder) {
encoder = new TextEncoder();
}
let uint8array = encoder.encode(JSON.stringify(data));
return uint8array;
},
subscribe(topic, callback) {
if (!topic) {
return topic;
}
let {
client
} = this.mqtt;
if (client) {
console.log(topic, 'topic------------');
client.subscribe(topic, callback);
}
},
unsubscribe(topic) {
if (!topic) {
return topic;
}
let {
client
} = this.mqtt;
if (client) {
client.unsubscribe(topic);
}
},
uuidFn() {
let random
let uuid = ''
for (let i = 0; i < 32; i++) {
random = Math.random() * 16 | 0; // 解释1
if (i === 8 || i === 12 || i === 16 || i === 20) { // 解释2
uuid += '-';
}
uuid += (i === 12 ? 4 : (i === 16 ? (random & 3 | 8) : random)).toString(16); // 解释3
}
return uuid;
},
initMqtt() {
try {
if (this.mqtt.client) {
this.mqtt.client.end();
this.mqtt.client = null;
}
let url = VUE_APP_MQTT_URL;
let protocol = url.replace(/(.+)\:\/\/.*/, "$1");
this.mqtt.client = mqtt.connect(url, {
protocol,
clientId: this.uuidFn(),
});
this.mqtt.client.on("connect", () => {
console.log('订阅成功');
});
this.mqtt.client.on("reconnect", function (reconnect) { });
this.mqtt.client.on("`error`", (error) => { });
this.mqtt.client.on("message", (topic, payload, packet) => {
let data = this.uint8array2json(payload);
// let {
// latitude,
// longitude
// } = data;
// // 将经纬度转换为 Cartographic 坐标
// let positionCartographic = Cesium.Cartographic.fromDegrees(longitude, latitude);
// // 将 Cartographic 坐标转换为 Cartesian3 坐标
// let positionCartesian = Cesium.Cartographic.toCartesian(positionCartographic);
// this.positions = positionCartesian
// // this.customProperty = data
// // for (let key in data.airData) {
// // let item = data.airData[key];
// // this.$set(this.airData, key, item)
// // //
// // this.calibrationGas(key, item)
// // }
});
let GAStopic = this.GAStopic
console.log(GAStopic, 'GAStopic');
// 订阅数据
this.subscribe(GAStopic)
} catch (error) {
console.log(error, 'errorerror');
}
},
calibrationGas(item) {
let flag = false
let num = null
let max = null
let name = null
if (item.co > item.coThreshold) {
name = 'CO'
num = item.co
max = item.coThreshold
flag = true
} else if (item.no2 > item.no2Threshold) {
name = 'NO2'
num = item.no2
max = item.no2Threshold
flag = true
}
else if (item.ox > item.oxThreshold) {
name = 'OX'
num = item.ox
max = item.oxThreshold
flag = true
} else if (item.pm1dot0 > item.pm1dot0Threshold) {
name = 'PM1.0'
num = item.pm1dot0
max = item.pm1dot0Threshold
flag = true
} else if (item.pm10 > item.pm10Threshold) {
name = 'PM10'
num = item.pm10
max = item.pm10Threshold
flag = true
} else if (item.pm2dot5 > item.pm2dot5Threshold) {
name = 'PM2.5'
num = item.pm10
max = item.pm2dot5Threshold
flag = true
} else if (item.so2 > item.so2Threshold) {
name = 'So2'
num = item.so2
max = item.so2Threshold
flag = true
}
if (flag) {
this.warningInfor = {
title: "危险提示",
msg: '检测到气体' + name + '数值为' + num + ',大于' + max + '已对人体造成伤害,请注意防护!'
}
this.visible = true
}
},
}
\ No newline at end of file
// 创建弹窗对象的方法
var Popup = function (info) {
this.constructor(info);
}
Popup.prototype.id = 0;
Popup.prototype.constructor = function (info) {
var _this = this;
_this.viewer = info.viewer;//弹窗创建的viewer
_this.geometry = info.geometry;//弹窗挂载的位置
let data = null
if (info.data && info.data._properties && info.data._properties._customProperty._value) {
data = info.data._properties._customProperty._value.airData
}
_this.data = data;
_this.del_real = info.del_real;
_this.vueThis = info.arr;
_this.id = "popup_" + _this.__proto__.id++;
_this.ctn = $("<div class='bx-popup-ctn' id='" + _this.id + "'>");
$(_this.viewer.container).append(_this.ctn);
let contentHtml = ''
/**
* 增加单位名称
*/
if (_this.data['co']) {
contentHtml += `<div class="li"><div class="label">CO(ppm):</div><div class="text cf" style="width: 160px;">${_this.data['co']}</div></div>`
}
if (_this.data['no2']) {
contentHtml += `<div class="li"><div class="label">NO2(ppm):</div><div class="text cf">${_this.data['no2']}</div></div>`
}
if (_this.data['ox']) {
contentHtml += `<div class="li"><div class="label">Ox(ppm):</div><div class="text cf">${_this.data['ox']}</div></div>`
}
if (_this.data['pm1dot0']) {
contentHtml += `<div class="li"><div class="label">PM1.0(ug/m3):</div><div class="text cf">${_this.data['pm1dot0']}</div></div>`
}
if (_this.data['pm2dot5']) {
contentHtml += `<div class="li"><div class="label">PM2.5(ug/m3):</div><div class="text cf">${_this.data['pm2dot5']}</div></div>`
}
if (_this.data['pm10']) {
contentHtml += `<div class="li"><div class="label">PM10(ug/m3):</div><div class="text cf">${_this.data['pm10']}</div></div>`
}
if (_this.data['so2']) {
contentHtml += `<div class="li"><div class="label">SO2(ppm):</div><div class="text cf" >${_this.data['so2']}</div></div>`
}
//测试弹窗内容
var testConfig = {
header: '检测内容',
content: `<div>${contentHtml}</div>`,
}
_this.ctn.append(_this.createHtml(testConfig.header, testConfig.content));
// 实时刷新
_this.offsetWidth = _this.ctn.get(0).offsetWidth
_this.offsetHeight = _this.ctn.get(0).offsetHeight
_this.render(_this.geometry);
_this.eventListener = () => { // 每一帧都去计算气泡的正确位置
_this.render(_this.geometry);
}
_this.viewer.scene.postRender.addEventListener(_this.eventListener);
_this.ctn.on("click", ".leaflet-popup-close-button", function (e) {
e.stopPropagation();
_this.close();
});
}
Popup.prototype.render = function (geometry) {
var _this = this;
var position = Cesium.SceneTransforms.wgs84ToWindowCoordinates(_this.viewer.scene, geometry)
_this.ctn.css("left", position.x - _this.offsetWidth / 2);
_this.ctn.css("top", position.y - _this.offsetHeight - 10);
}
// 动态生成内容
Popup.prototype.createHtml = function (header, content) {
var html = '<div class="bx-popup-header-ctn" style="color: #5eefff;text-align:center;font-weight: 700;">' +
header +
'</div>' +
// '<div class="bx-popup-content-ctn" >' +
'<div class="bx-popup-content" style="color: aqua;margin-left: 15px;}" >' +
content +
'</div>' +
'</div>' +
'<div class="bx-popup-tip-container" >' +
'<div class="bx-popup-tip" >' +
'</div>' +
'</div>' +
'<div class="el-icon-close leaflet-popup-close-button"></div>';
return html;
}
// 关闭弹窗按钮
Popup.prototype.close = function () {
var _this = this;
const { category, deviceHardId } = _this.data
_this.ctn.remove();
if (category === 1) {
_this.del_real(deviceHardId)
}
// _this.viewer.clock.onTick.removeEventListener(_this.eventListener);
_this.viewer.scene.postRender.removeEventListener(_this.eventListener);
// 防止点击关闭无法创建新的移动弹窗
// console.log('this.data132564',this.data);
// if (this.data.hasOwnProperty('regionList')) {
const index = _this.vueThis.move_id_arr.indexOf('_this.data.id');
_this.vueThis.move_id_arr.splice(index, 1)
// }
}
export default Popup
\ No newline at end of file
<template>
<div class="cpt-MMC_Gimbal_L50" v-interact>
<div class="hd">
<div class="title">探照灯</div>
</div>
<div class="bd">
<div class="form-wrap">
<div class="form-item">
<div class="label-box">常规模式</div>
<div class="input-box">
<el-switch v-model="bright_status" size="mini" @change="handle_bright" />
</div>
</div>
<div v-if="!bright_status" class="form-item">
<div class="label-box">闪光模式</div>
<div class="input-box">
<el-switch v-model="flicker_status" size="mini" @change="handle_flicker" />
</div>
</div>
<div v-else class="form-item">
<div class="label-box">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div class="input-box">
<el-checkbox v-model="very_bright_status" size="mini" @change="handle_very_bright" />
</div>
</div>
<div class="form-item">
<div class="label-box">回中开关</div>
<div class="input-box">
<el-switch v-model="middle_status" size="mini" @change="handle_middle" />
</div>
</div>
</div>
<div class="rocker-wrap">
<div class="title-box">
<div class="title">俯仰操作</div>
</div>
<div ref="rocker" class="rocker">
<div class="shangUp" @click="fangxiang('up')" />
<div class="xaiUp" @click="fangxiang('down')" />
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_L50 } from '../utils';
export default {
data() {
return {
timer: null,
bright_status: false,
flicker_status: false,
very_bright_status: false,
middle_status: false
};
},
mounted() {
this.$nextTick(() => {
this.init_rocker();
});
},
methods: {
handle_bright(value) {
const buffer = MMC_Gimbal_L50.constant_bright_ctrl(value);
this.commit_directive(buffer);
},
handle_flicker(value) {
const buffer = MMC_Gimbal_L50.flicker_ctrl(!value);
this.commit_directive(buffer);
},
handle_very_bright(value) {
const buffer = MMC_Gimbal_L50.very_bright_ctrl(!value);
this.commit_directive(buffer);
},
handle_middle(value) {
const buffer = MMC_Gimbal_L50.middle_ctrl(!value);
this.commit_directive(buffer);
},
commit_directive(buffer) {
this.$emit('directive', buffer);
},
fangxiang(type) {
let buffer = null;
switch (type) {
case 'up':
buffer = MMC_Gimbal_L50.gimbal_pitch_ctrl(1, this.control_speed);
this.commit_directive(buffer);
break;
case 'right':
// _this.gimbal_yaw_ctrl(1);
break;
case 'left':
// _this.gimbal_yaw_ctrl(-1);
break;
case 'down':
buffer = MMC_Gimbal_L50.gimbal_pitch_ctrl(-1, this.control_speed);
this.commit_directive(buffer);
}
// this.timer = setTimeout(() => {
// clearTimeout(this.timer);
// buffer = gimbal_pitch_ctrl(0, this.control_speed);
// this.commit_directive(buffer);
// }, 500);
},
init_rocker() {
let buffer = null;
joystick({
// zone: this.$refs["rocker"],
// mode: "static",
// position: { left: "50%", top: "50%" },
// color: "#9bacbe",
onstart: (type) => {
switch (type) {
case 'up':
buffer = MMC_Gimbal_L50.gimbal_pitch_ctrl(1, this.control_speed);
this.commit_directive(buffer);
break;
case 'right':
// _this.gimbal_yaw_ctrl(1);
break;
case 'left':
// _this.gimbal_yaw_ctrl(-1);
break;
case 'down':
buffer = MMC_Gimbal_L50.gimbal_pitch_ctrl(-1, this.control_speed);
this.commit_directive(buffer);
}
},
onend: () => {
// buffer = gimbal_pitch_ctrl(0, this.control_speed);
// this.commit_directive(buffer);
}
});
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_L50 {
position: absolute;
top: 0px;
right: 0;
/* background: center url("../assets/images/observe/fckernel/mount/01_bg.png")
no-repeat; */
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
background-size: 100% 100%;
width: 500px;
height: 290px;
box-sizing: border-box;
padding: 10px 20px;
.hd {
.title {
font-size: 18px;
color: #08c2d1;
font-weight: bold;
line-height: 2;
}
}
.bd {
display: flex;
justify-content: space-between;
.form-wrap {
min-width: 245px;
flex-shrink: 0;
.form-item {
display: flex;
align-items: center;
height: 40px;
.label-box {
color: #cbd0eb;
width: 75px;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
}
.rocker-wrap {
flex: 1;
.title-box {
.title {
color: #cbd0eb;
}
}
.rocker {
margin: 10px auto 0;
width: 154px;
height: 154px;
background: -0.5px 3.5px url('../assets/images/accident/operation.png') no-repeat;
background-size: 100% calc(100% - 3.5px);
position: relative;
.shangUp {
position: absolute;
left: 34%;
top: 0px;
border-radius: 50%;
width: 50px;
height: 50px;
border: 0px solid red;
cursor: pointer;
}
.xaiUp {
position: absolute;
left: 34%;
bottom: 0px;
border-radius: 50%;
width: 50px;
height: 50px;
border: 0px solid red;
cursor: pointer;
}
}
}
}
}
::v-deep {
.el-select {
width: 165px;
margin-right: 5px;
.el-input {
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
}
.el-input {
width: 165px;
margin-right: 5px;
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
.el-radio-group {
.el-radio {
.el-radio__input {
&.is-checked {
.el-radio__inner {
border-color: #08c2d1;
background: #08c2d1;
}
}
}
.el-radio__label {
color: #cbd0eb;
}
}
}
.el-button {
background: #2aefed;
color: #000;
border: none;
}
}
</style>
<template>
<div class="cpt-MMC_Gimbal_P0_Pro" v-interact>
<div class="hd">
<div class="title">喊话器</div>
</div>
<div class="bd">
<div class="form-wrap">
<div class="form-item">
<div class="label-box">喊话播放</div>
<div class="input-box">
<div class="icon-box">
<span class="el-icon-video-play" @click="handle_play" />
<span class="el-icon-video-pause" @click="handle_pause" />
</div>
</div>
</div>
<div class="form-item">
<div class="label-box">&nbsp;&nbsp;</div>
<div class="input-box">
<el-select
v-model="music"
size="mini"
placeholder="请选择下一曲"
@change="handle_change_music"
>
<el-option :label="1" :value="1" />
<el-option :label="2" :value="2" />
<el-option :label="3" :value="3" />
</el-select>
</div>
</div>
<div class="form-item">
<div class="label-box">控制速度</div>
<div class="input-box">
<div class="speedC">
<div
v-for="(item, index) in new Array(5).fill(1)"
:key="index"
class="speed"
:style="control_speed == index + 1 ? 'background: #FFFFFF;color: #333333;' : ''"
@click="control_speed = index + 1"
>
{{ index + 1 }}
</div>
</div>
<!-- <el-select
v-model="control_speed"
size="mini"
placeholder="请选择控制速度"
>
<el-option
v-for="(item, index) in new Array(5).fill(1)"
:key="index"
:label="index + 1"
:value="index + 1"
></el-option>
</el-select> -->
</div>
</div>
</div>
<div class="rocker-wrap">
<div class="title-box">
<div class="title">俯仰操作</div>
</div>
<div ref="rocker" class="rocker">
<div class="shangUp" @click="fangxiang('up')" />
<div class="xaiUp" @click="fangxiang('down')" />
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_P0_Pro } from '../utils';
export default {
data() {
return {
timer: null,
music: null,
control_speed: 3
};
},
mounted() {
this.$nextTick(() => {
this.init_rocker();
});
},
methods: {
handle_play() {
const buffer = MMC_Gimbal_P0_Pro.gimbal_audio_play_ctl(2);
this.commit_directive(buffer);
},
handle_pause() {
const buffer = MMC_Gimbal_P0_Pro.gimbal_audio_play_ctl(0);
this.commit_directive(buffer);
},
handle_change_music() {
const buffer = MMC_Gimbal_P0_Pro.gimbal_audio_play_next_ctl();
this.commit_directive(buffer);
},
commit_directive(buffer) {
this.$emit('directive', buffer);
},
fangxiang(type) {
let buffer = null;
switch (type) {
case 'up':
buffer = MMC_Gimbal_P0_Pro.gimbal_pitch_ctrl(1, this.control_speed);
this.commit_directive(buffer);
break;
case 'right':
// _this.gimbal_yaw_ctrl(1);
break;
case 'left':
// _this.gimbal_yaw_ctrl(-1);
break;
case 'down':
buffer = MMC_Gimbal_P0_Pro.gimbal_pitch_ctrl(-1, this.control_speed);
this.commit_directive(buffer);
}
this.timer = setTimeout(() => {
clearTimeout(this.timer);
buffer = MMC_Gimbal_P0_Pro.gimbal_pitch_ctrl(0, this.control_speed);
this.commit_directive(buffer);
}, 500);
},
init_rocker() {
let buffer = null;
joystick({
// zone: this.$refs["rocker"],
// mode: "static",
// position: { left: "50%", top: "50%" },
// color: "#9bacbe",
onstart: (type) => {
switch (type) {
case 'up':
buffer = MMC_Gimbal_P0_Pro.gimbal_pitch_ctrl(1, this.control_speed);
this.commit_directive(buffer);
break;
case 'right':
// _this.gimbal_yaw_ctrl(1);
break;
case 'left':
// _this.gimbal_yaw_ctrl(-1);
break;
case 'down':
buffer = MMC_Gimbal_P0_Pro.gimbal_pitch_ctrl(-1, this.control_speed);
this.commit_directive(buffer);
}
},
onend: () => {
buffer = MMC_Gimbal_P0_Pro.gimbal_pitch_ctrl(0, this.control_speed);
this.commit_directive(buffer);
}
});
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_P0_Pro {
position: absolute;
top: 0px;
right: 0;
/* background: center url("../assets/images/observe/fckernel/mount/01_bg.png")
no-repeat; */
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
background-size: 100% 100%;
width: 500px;
height: 290px;
box-sizing: border-box;
padding: 10px 20px;
.hd {
.title {
font-size: 18px;
color: #08c2d1;
font-weight: bold;
line-height: 2;
}
}
.bd {
display: flex;
justify-content: space-between;
.form-wrap {
flex-shrink: 0;
.form-item {
display: flex;
align-items: center;
height: 40px;
.label-box {
color: #cbd0eb;
width: 75px;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
}
.rocker-wrap {
flex: 1;
.title-box {
.title {
color: #cbd0eb;
}
}
.rocker {
margin: 10px auto 0;
width: 154px;
height: 154px;
background: -0.5px 3.5px url('../assets/images/accident/operation.png') no-repeat;
background-size: 100% calc(100% - 3.5px);
position: relative;
.shangUp {
position: absolute;
left: 34%;
top: 0px;
border-radius: 50%;
width: 50px;
height: 50px;
border: 0px solid red;
cursor: pointer;
}
.xaiUp {
position: absolute;
left: 34%;
bottom: 0px;
border-radius: 50%;
width: 50px;
height: 50px;
border: 0px solid red;
cursor: pointer;
}
}
}
}
}
::v-deep {
.el-select {
width: 165px;
margin-right: 5px;
.el-input {
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
}
.el-input {
width: 165px;
margin-right: 5px;
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
.el-radio-group {
.el-radio {
.el-radio__input {
&.is-checked {
.el-radio__inner {
border-color: #08c2d1;
background: #08c2d1;
}
}
}
.el-radio__label {
color: #cbd0eb;
}
}
}
.el-button {
background: #2aefed;
color: #000;
border: none;
}
}
::v-deep .el-slider__bar {
background: #fff;
}
.speedC {
width: 203px;
height: 24px;
display: flex;
background: rgba(13, 34, 79, 0.65);
border: 1px solid #43deff;
border-radius: 12px;
.speed {
width: 41px;
// background: #FFFFFF;
color: #ffffff;
border-radius: 12px;
text-align: center;
line-height: 24px;
}
}
.iconfont {
color: #2aefed;
}
</style>
<template>
<Popup
class="p1 w200"
:container-style="{
top: '215px',
right: '100px',
height: '465px'
}"
>
<div class="PopupBox" v-interact>
<div class="hd">
<div class="Popup h40 lh40 jcsb">
<div class="ml30 jcsb">
<img class="w20 h20 mt6" src="../assets/images/mount/mount_head.png" />
<div class="title mt5">水体采样器</div>
</div>
<div class="mr10 cp cf f14 fw300" @click="$emit('close')">关闭</div>
</div>
</div>
<div class="wih100 tc">
<div
class="dib cp tc w150 h40 lh40 tc cp mt10 selectCollectionButton"
@mousedown="declineFn"
@mouseup="stop"
@mouseout="stop"
>
下降采集
</div>
</div>
<div class="wih100 tc mt10">
<div
class="dib cp tc w150 h40 lh40 tc selectCollectionButton"
@mousedown="upFn"
@mouseup="stop"
@mouseout="stop"
>
上升回收
</div>
</div>
<div class="wih100 tc dib" style="margin: 0 auto">
<div class="dib tc w146 pr">
<div class="tc mt20">
<div class="pa left25">
<div
:class="isFull ? 'selectFull' : ''"
class="dib cp defaultCollectionButton Collection w90 h38 lh38 tc"
:style="`transform:translateY(${num}px)`"
>
采集器
</div>
</div>
</div>
<img class="w146 h246 mt30" src="../assets/images/accident/Collection.svg" alt />
</div>
</div>
</div>
</Popup>
</template>
<script>
import Popup from '../components/popup';
import { mapGetters } from 'vuex';
import { MMC_Gimbal_QS } from '../utils';
export default {
components: {
Popup
},
data() {
return {
num: 0,
// 下降定时器
timerflag: '',
// 上升定时器
timerflagtwo: '',
isFull: false
};
},
computed: {
...mapGetters(['user_info'])
},
methods: {
commit_directive(buffer) {
console.log(buffer);
this.$emit('directive', buffer);
},
// 下降
declineFn() {
this.timerflag = setInterval(() => {
if (this.num <= 300) {
const buffer = MMC_Gimbal_QS.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
this.num += 0.1;
} else {
this.isFull = true;
clearInterval(this.timerflag);
}
console.log(this.num);
}, 20);
},
// 上升回收
upFn() {
// this.declineFlag = false;
clearInterval(this.timerflagtwo);
this.timerflagtwo = setInterval(() => {
const buffer = MMC_Gimbal_QS.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
if (this.num >= 0) {
this.num -= 0.1;
} else {
clearInterval(this.timerflagtwo);
}
}, 20);
},
stop() {
const buffer = MMC_Gimbal_QS.gimbal_pitch_ctrl(0);
this.commit_directive(buffer);
clearInterval(this.timerflag);
clearInterval(this.timerflagtwo);
}
}
};
</script>
<style lang="scss" scoped>
.suspendedbox {
background: #494d57;
border: 1px solid #78838f;
color: #979da2;
width: 150px;
margin: auto;
:hover {
color: #00f3ef;
box-shadow: inset 0 0 11px 0 #00f3ef;
}
}
.title_header {
color: #dce9ff;
font-family: PangMenZhengDao;
}
.defaultCollectionButton {
background: #494d57;
border: 1px solid #78838f;
color: #979da2;
}
.Collection {
border-radius: 8px;
}
.defaultDeclineFlag {
margin-top: 0px;
top: 20px;
transition: 10s;
}
.declineFlag {
top: 20px;
margin-top: 200px;
transition: 10s;
}
.selectFull {
color: #000;
border: 1px solid #2aefed;
background-color: #2aefed;
}
.selectCollectionButton {
background: #076362;
border: 1px solid #2aefed;
color: #00f3ef;
box-shadow: inset 0 0 11px 0 #00f3ef;
}
.selectCollectionButton:hover {
background: #0c9b98;
}
.shoutImg {
background-image: url('../assets/images/accident/operation.png');
background-repeat: no-repeat;
background-size: 100%;
}
.bfsx {
background-image: url('../assets/images/accident/shunxu.png');
background-position: 49px 30px;
width: 37px;
}
.Popup {
background: rgba(16, 65, 215, 0.2);
box-shadow: inset 0 0 15px 0 rgba(0, 182, 255, 0.6);
border-radius: 10px 10px 0 0;
.title {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.PopupBox {
background: rgba(12, 34, 73, 0.7);
border-radius: 10px;
border: 1px solid rgba(26, 92, 246, 0.5);
-webkit-backdrop-filter: blur(1px);
backdrop-filter: blur(1px);
background-size: 100% 100%;
}
</style>
<template>
<div class="cpt-MMC_Gimbal_S1" v-interact>
<div class="hd">
<div class="title">抛投</div>
</div>
<div class="bd">
<div class="form-wrap">
<div class="form-item">
<div class="label-box">预设重量</div>
<div class="input-box">
<div class="text-box">{{ height }}</div>
</div>
</div>
<div class="form-item">
<div class="label-box">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div class="input-box">
<div class="text-box">正常</div>
</div>
</div>
<div class="form-item">
<div class="label-box">智能模式</div>
<div class="input-box">
<el-switch
v-model="lntelligent_mode_status"
size="mini"
@change="handle_change_lntelligent_mode_ctrl"
/>
</div>
</div>
<div class="form-item">
<div class="label-box">执行动作</div>
<div class="input-box">
<el-switch
v-model="motor_weight_status"
size="mini"
@change="handle_change_motor_weight"
/>
</div>
</div>
<div class="form-item">
<div class="label-box">重量(g)</div>
<div class="input-box">
<el-input v-model="pre_height" size="mini" placeholder="请输入重量" />
<el-button size="mini" type="primary"
@click="height = pre_height">预设</el-button>
</div>
</div>
</div>
<div class="rocker-wrap">
<img src="../assets/images/observe/006.svg" class="dib w200 h200" alt="" />
<!-- <div class="title-box">
<div class="title">俯仰操作</div>
</div>
<div class="rocker" ref="rocker">
<div class="shangUp" @click="fangxiang('up')"></div>
<div class="xaiUp" @click="fangxiang('down')"></div>
</div> -->
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_S1 } from '../utils';
export default {
data() {
return {
timer: null,
height: 300,
pre_height: 300,
lntelligent_mode_status: false,
motor_weight_status: false
};
},
mounted() {
this.$nextTick(() => {
this.init_rocker();
});
},
methods: {
handle_change_lntelligent_mode_ctrl(value) {
const buffer = MMC_Gimbal_S1.lntelligent_mode_ctrl(value);
this.commit_directive(buffer);
},
handle_change_motor_weight(value) {
const buffer = MMC_Gimbal_S1.motor_weight(value);
this.commit_directive(buffer);
},
commit_directive(buffer) {
this.$emit('directive', buffer);
},
fangxiang(type) {
let buffer = null;
switch (type) {
case 'up':
buffer = MMC_Gimbal_S1.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
break;
case 'right':
// _this.gimbal_yaw_ctrl(1);
break;
case 'left':
// _this.gimbal_yaw_ctrl(-1);
break;
case 'down':
buffer = MMC_Gimbal_S1.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
}
// this.timer = setTimeout(() => {
// clearTimeout(this.timer);
// // buffer = gimbal_pitch_ctrl(0, this.control_speed);
// // this.commit_directive(buffer);
// }, 500);
},
init_rocker() {
let buffer = null;
joystick({
// zone: this.$refs["rocker"],
// mode: "static",
// position: { left: "50%", top: "50%" },
// color: "#9bacbe",
onstart: (type) => {
switch (type) {
case 'up':
buffer = MMC_Gimbal_S1.gimbal_pitch_ctrl(1);
this.commit_directive(buffer);
break;
case 'right':
// _this.gimbal_yaw_ctrl(1);
break;
case 'left':
// _this.gimbal_yaw_ctrl(-1);
break;
case 'down':
buffer = MMC_Gimbal_S1.gimbal_pitch_ctrl(-1);
this.commit_directive(buffer);
}
},
onend: () => {
// buffer = gimbal_pitch_ctrl(0, this.control_speed);
// this.commit_directive(buffer);
}
});
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_S1 {
position: absolute;
top: 0px;
right: 0;
/* background: center url("../assets/images/observe/fckernel/mount/01_bg.png")
no-repeat; */
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
background-size: 100% 100%;
width: 500px;
height: 290px;
box-sizing: border-box;
padding: 10px 20px;
.hd {
.title {
font-size: 18px;
color: #08c2d1;
font-weight: bold;
line-height: 2;
}
}
.bd {
display: flex;
justify-content: space-between;
.form-wrap {
flex-shrink: 0;
.form-item {
display: flex;
align-items: center;
height: 40px;
.label-box {
color: #cbd0eb;
width: 75px;
}
.input-box {
display: flex;
align-items: center;
.text-box {
color: #dce9ff;
}
}
}
}
.rocker-wrap {
flex: 1;
.title-box {
.title {
color: #cbd0eb;
}
}
.rocker {
margin: 10px auto 0;
width: 154px;
height: 154px;
background: -0.5px 3.5px url('../assets/images/accident/operation.png') no-repeat;
background-size: 100% calc(100% - 3.5px);
position: relative;
.shangUp {
position: absolute;
left: 34%;
top: 0px;
border-radius: 50%;
width: 50px;
height: 50px;
border: 0px solid red;
cursor: pointer;
}
.xaiUp {
position: absolute;
left: 34%;
bottom: 0px;
border-radius: 50%;
width: 50px;
height: 50px;
border: 0px solid red;
cursor: pointer;
}
}
}
}
}
::v-deep {
.el-select {
width: 165px;
margin-right: 5px;
.el-input {
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
}
.el-input {
width: 165px;
margin-right: 5px;
.el-input__inner {
background: #000000;
border: 1px solid #08c2d1;
color: #dce9ff;
}
}
.el-radio-group {
.el-radio {
.el-radio__input {
&.is-checked {
.el-radio__inner {
border-color: #08c2d1;
background: #08c2d1;
}
}
}
.el-radio__label {
color: #cbd0eb;
}
}
}
.el-button {
background: #2aefed;
color: #000;
border: none;
}
}
</style>
<template>
<div class="cpt-MMC_Gimbal_S79" :style="containerStyle" v-interact>
<div class="hd">
<div class="left ml8">
<img src="../assets/images/mount/mount_head.png" />
<div class="title">射击枪</div>
</div>
<div class="close" @click="$emit('close')">关闭</div>
</div>
<div class="bd">
<div class="form-wrap">
<div class="form-item">
<div class="label-box">保险:</div>
<div class="input-box">
<el-switch v-model="safety_switch_state" size="mini" />
</div>
</div>
<div class="form-item mt16">
<img src="../assets/images/observe/005.svg" alt="" />
<div class="launch">
<img src="../assets/images/mount/launch.png" alt @click="handle_laser_shine_ctrl" />
<div class="label-box">发射</div>
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import { MMC_Gimbal_S79 } from '../utils';
export default {
props: {
containerStyle: {
type: Object,
default: () => ({})
}
},
data() {
return {
timer: null,
radio: 1,
safety_switch_state: true
};
},
mounted() {},
methods: {
handle_laser_shine_ctrl(value) {
if (this.safety_switch_state) {
this.$message.warning('请关闭保险');
} else {
const buff = MMC_Gimbal_S79.fire_ctrl(1);
this.commit_directive(buff);
this.$message.success('发射成功');
}
},
commit_directive(buffer) {
// console.log(buffer);
this.$emit('directive', buffer);
}
}
};
</script>
<style lang="scss" scoped>
.cpt-MMC_Gimbal_S79 {
position: absolute;
// bottom: 0;
right: 0;
background: rgba(0, 23, 79, 0.7);
box-shadow: 0 2px 4px 0 rgba(1, 162, 255, 0.35), inset 0 0 40px 0 rgba(0, 184, 255, 0.5);
border-radius: 10px;
width: 240px;
box-sizing: border-box;
.hd {
height: 32px;
display: flex;
justify-content: space-between;
align-items: center;
background: rgba(16, 65, 215, 0.2);
box-shadow: inset 0 0 15px 0 rgba(0, 182, 255, 0.6);
border-radius: 10px 10px 0 0;
.left {
display: flex;
align-items: center;
.title {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.close {
font-size: 14px;
font-family: MicrosoftYaHei;
color: #d2dfff;
margin-right: 8px;
cursor: pointer;
}
}
.bd {
display: flex;
.form-wrap {
padding: 16px 0;
width: 100%;
height: 130px;
display: flex;
flex-direction: column;
align-items: center;
justify-content: space-around;
.form-item {
display: flex;
align-items: center;
.label-box {
color: #cbd0eb;
}
.input-box {
display: flex;
align-items: center;
.icon-box {
[class^='el-icon-'] {
font-size: 30px;
color: #dce9ff;
}
}
}
}
.launch {
margin-left: 16px;
display: flex;
flex-direction: column;
align-items: center;
}
}
}
}
</style>
<template>
<div class="angleControlBox mt16">
<div class="angleControlBg w99 h99 dib">
<div class="dib wih100 ht100 pr">
<div class="angleControlLB tc w40 ml50 mt40 h30" />
<img class="pa top0 left21" src="./assets/LBT2.png" alt />
<div class="light pa left30 top20" :style="`transform: rotate(${90 - rotate}deg);`">
<img src="./assets/LB2.png" alt />
</div>
<div class="iconfont icon-zuo1 pa top40 left15 c08c" />
<div class="rolate iconfont icon-zuo1 pa top40 right15 c08c" />
</div>
</div>
<div class>
<img class src="./assets/jd.png" alt />
<span class="dib vas cf">角度调节</span>
</div>
<div class="h56 wih100 bg tc">
<div class="AngleControl dib w100 h56 tc pr">
<div
class="left5 top18 pa w28 lh28 h28 left cp"
@mousedown="rotateFn(1)"
@mouseup="stopFn()"
>
<div class="iconfont icon-zuo1" />
</div>
<div
class="pa right5 top18 w28 lh28 h28 right cp"
@mousedown="rotateFn(-1)"
@mouseup="stopFn()"
>
<div class="rolate mr5 iconfont icon-zuo1" />
</div>
</div>
</div>
<div class="mt12 cf f16">
<img class="dib w24 h24 mr10" src="./assets/Voice.png" alt />
<div class="dib vas">音量调节</div>
<div class="jcsb pl20 mr10">
<div
class="dib rightBtn mr5"
@mousedown="handleChangeVolume(-1)"
@mouseup="stophandleChangeVolume()"
>
<img class src="./assets/del.png" alt />
</div>
<el-progress
class="w120 lh1.3"
:text-inside="true"
:percentage="volume"
:stroke-width="17"
/>
<div
class="dib rightBtn ml5"
@mousedown="handleChangeVolume(1)"
@mouseup="stophandleChangeVolume()"
>
<img class src="./assets/plus.png" alt />
</div>
</div>
</div>
</div>
</template>
<script>
import CmdSetSystemVolume from '../utils/cmd_set_system_volume'; // 设置系统音量
import CmdServoAngle from '../utils/cmd_servo_angle'; // 设置偏转角
export default {
props: {
rotate: {
type: Number,
default: 0
},
volume: {
type: Number,
default: 0
}
},
data() {
return {
// volume: 0,
// rotate: 0,
time: '',
handleChangeVolumeTime: ''
};
},
mounted() {
// setTimeout(() => {
// this.volume = this.PagerP1.volume;
// this.rotate = this.PagerP1.angle;
// }, 1000);
},
inject: ['PagerP1', 'PoliceKey'],
methods: {
stopFn() {
clearInterval(this.time);
},
rotateFn(type) {
clearInterval(this.time);
if (type == 1) {
this.time = setInterval(() => {
if (this.rotate < 60) {
this.rotate++;
const message = {
data: this.rotate,
type: 2314
};
this.mqtt_publish(message);
// this.rotate++;
}
}, 100);
} else {
this.time = setInterval(() => {
if (this.rotate > 0) {
this.rotate--;
const message = {
data: this.rotate,
type: 2314
};
this.mqtt_publish(message);
// this.rotate--;
}
}, 100);
}
},
// 控制音量 start
handleChangeVolume(cate) {
this.stophandleChangeVolume();
this.handleChangeVolumeTime = setInterval(() => {
if ((this.volume == 0 && cate == -1) || (this.volume == 100 && cate == 1)) {
return;
}
this.volume += cate;
const message = {
data: this.volume,
type: 2315
};
this.mqtt_publish(message);
}, 100);
},
stophandleChangeVolume() {
clearInterval(this.handleChangeVolumeTime);
},
async mqtt_publish(message) {
if (this.PoliceKey()) {
const key = await this.PoliceKey();
this.PagerP1.mqtt.client.publish(
`SPEAK/OBTAIN/${key}-01`,
new TextEncoder().encode(JSON.stringify(message)),
{
qos: 0
},
(e) => {
// console.log("发送指令成功:", message);
}
);
}
},
mqtt_json2uint8array(data) {
if (!data) {
return data;
}
let { encoder } = this.PagerP1.mqtt;
if (!encoder) {
encoder = new TextEncoder();
}
const uint8array = encoder.encode(JSON.stringify(data));
return uint8array;
}
// 控制音量 end
}
};
</script>
<style lang="scss" scoped>
.angleControlBox {
width: 127px;
margin: 0 auto;
text-align: center;
.left21 {
z-index: 10;
}
.angleControlBg {
background-image: url('./assets/bg2.png');
background-repeat: no-repeat;
background-size: 100%;
.angleControlLB {
transform-origin: 50% 0px;
// background-image: url("~./assets/LB2.png");
background-repeat: no-repeat;
}
}
.rightBtn {
box-sizing: border-box;
border-radius: 50%;
// border: 1px solid #08c2d1;
width: 16px;
height: 16px;
// line-height: 20px;
// text-align: center;
cursor: pointer;
// font-size: 20px;
padding-left: 1px;
&:hover {
opacity: 0.7;
}
}
.AngleControl {
background-image: url('./assets/jdbj2.png');
background-repeat: no-repeat;
background-size: 100%;
.left {
border-radius: 50%;
color: #3d4654;
background: #9aabbd;
}
.left:hover {
color: #08c2d1;
}
.right {
border-radius: 50%;
color: #3d4654;
background: #9aabbd;
}
.right:hover {
color: #08c2d1;
}
}
}
.rolate {
transform: rotateY(180deg);
}
.c08c {
color: #08c2d1;
}
::v-deep .el-progress-bar__innerText {
color: #000;
}
.right5 {
right: -10px;
}
</style>
<template>
<div class="itemAMaxBox">
<el-input
v-model="text"
type="textarea"
placeholder="请输入想要发送的文字"
:disabled="write"
maxlength="70"
show-word-limit
/>
<div class="jcsb selectBox ml14 pr24 mt20">
<div>
<span> 语音:</span>
<el-select
v-model="value"
size="mini"
class="dib w100"
placeholder="请选择"
:disabled="write"
>
<el-option
v-for="item in options"
:key="item.value"
:label="item.label"
:value="item.value"
/>
</el-select>
</div>
<div>
<span> 速度:</span>
<el-select
v-model="value2"
size="mini"
class="dib w100"
placeholder="请选择"
popper-append-to-body
:disabled="write"
>
<el-option
v-for="item in options2"
:key="item.value2"
:label="item.label2"
:value="item.value2"
/>
</el-select>
</div>
<div>
<span> 重复:</span>
<el-select
v-model="ttsCycle"
size="mini"
class="dib w100"
placeholder="请选择"
@change="changeType"
>
<el-option
v-for="item in options3"
:key="item.ttsCycle"
:label="item.label3"
:value="item.ttsCycle"
/>
</el-select>
</div>
</div>
<div class="bottomBtnBox jcsb mt10 pl24 pr24">
<div class="cf f14">
<div class="w35 h35 lh35 tc">
<div class="w15 h15 ml5 iconfont" />
</div>
<div />
</div>
<div class="cf f14">
<div class="w30 h30 btnStyle tc" @click="handleSendTTSText">
<div v-if="flag" class="w5 cp h5 mt6 ml7 iconfont icon-a-bofang2px" />
<div v-else class="w20 cp h20 mt6 ml5 iconfont icon-a-zanting2px" />
</div>
<div>播放</div>
</div>
<div class="cf f14">
<div class="w45 h45 tc">
<div class="w5 h5 mt13 ml26 iconfontbf" />
</div>
<div />
</div>
<!-- <div class="cf f14">
<div class="w35 h35 btnStyle" @click="handleSendsupse">
<div class="w5 h5 mt10 ml9 iconfont icon-baocun1"></div>
</div>
<div>暂停</div>
</div> -->
</div>
</div>
</template>
<script>
import CmdTtsText from '../utils/cmd_tts_text';
import CMD_TTS_STATE from '../utils/cmd_record_state';
import MavLink20Processor from '../utils/mavlink20_processor';
import CmdReadFileList from '../utils/cmd_read_file_list';
import CmdRecordName from '../utils/cmd_record_name';
import CmdSetSystemVolume from '../utils/cmd_set_system_volume';
import CmdStreamFunction from '../utils/cmd_stream_function';
import CmdStreamUpData from '../utils/cmd_stream_up_data';
import CmdSaveFile from '../utils/cmd_save_file';
export default {
data() {
return {
text: '',
write: false,
ttsState: 10,
options: [
{
value: '1',
label: '普通话女'
},
{
value: '0',
label: '普通话男'
}
// {
// value: "xiaomei",
// label: "广东话",
// },
// {
// value: "xiaoqiang",
// label: "湖南话",
// },
// {
// value: "xiaorong",
// label: "四川话",
// },
// {
// value: "xiaoqian",
// label: "东北话",
// },
// {
// value: "xiaokun",
// label: "河南话",
// },
// {
// value: "xiaoying",
// label: "陕西话",
// },
],
value: '1',
options2: [
{
value2: '50',
label2: '正常'
},
{
value2: '100',
label2: '最快'
},
{
value2: '75',
label2: '较快'
},
{
value2: '25',
label2: '较慢'
},
{
value2: '0',
label2: '最慢'
}
],
value2: '50',
options3: [
{
ttsCycle: 10,
label3: '单次'
},
{
ttsCycle: 11,
label3: '循环'
}
// {
// ttsCycle: -1,
// label3: "未初始化",
// },
],
ttsCycle: 10,
flag: true
};
},
watch: {
ttsState: {
handler(val) {
if (val == 10) {
this.flag = true;
this.write = false;
} else {
this.flag = false;
this.write = true;
}
}
}
},
mounted() {
// setInterval(() => {
// this.ttsCycle = this.PagerP1.ttsCycle
// }, 100);
},
inject: ['PagerP1', 'PoliceKey'],
beforeDestroy() {
this.changeType(10);
this.handleSendsupse();
},
methods: {
changeType(e) {
const data = {
data: e,
type: 2307
};
this.mqtt_publish(data);
},
handleSendTTSText() {
if (this.text == '') return this.$message.info('文字不能为空!');
this.flag = false;
if (this.ttsState == 11) return;
if (!this.flag) {
// this.write = true;
let message = null;
const start = {
data: 11,
type: 2306
};
this.mqtt_publish(start);
message = {
data: {
text: this.text,
speed: this.value2,
voice: this.value
},
type: 2305
};
this.mqtt_publish(message);
this.$emit('playAudio', 13);
} else {
this.handleSendsupse();
}
},
handleSendsupse() {
// this.flag = true
// this.write = false;
const message = {
data: 10,
type: 2306
};
this.mqtt_publish(message);
},
async mqtt_publish(message) {
const key = await this.PoliceKey();
// console.log(`SPEAK/OBTAIN/${key}-01`, "发送主题");
this.PagerP1.mqtt.client.publish(
`SPEAK/OBTAIN/${key}-01`,
new TextEncoder().encode(JSON.stringify(message)),
{
qos: 0
},
(e) => {
console.log('发送指令成功:', message);
}
);
this.PagerP1.mqtt.client.on('message', (topic, payload, packet) => {
const data = JSON.parse(packet.payload.toString());
this.ttsState = data.ttsState;
});
}
}
};
</script>
<style lang="scss" scoped>
.itemAMaxBox {
width: 327px;
height: 231px;
text-align: center;
border-radius: 2px 2px 0px 0px;
border: 1px solid #315ec7;
.selectBox {
color: #b0b3be;
::v-deep el-select {
.el-input--mini {
background: #3768b3;
}
}
}
.bottomBtnBox {
.btnStyle {
cursor: pointer;
border-radius: 50%;
background: #9bacbe;
color: #3e495b;
border: 10px solid #000;
.bf {
transform: rotate(90deg);
}
}
.btnStyle:hover {
color: #315ec7;
}
}
}
::v-deep .el-textarea {
margin-top: 5px;
width: 315px;
height: 98px;
resize: none;
outline: none;
background: rgba(24, 39, 76, 0.7);
border: 1px solid #315ec7;
border-radius: 10px;
color: #d6d9df;
text-indent: 1em;
.el-textarea__inner {
width: 100% !important;
border: 1px solid #315ec7;
background: rgba(24, 39, 76, 0.7) !important;
}
textarea {
height: 98px;
}
.el-input__count {
background: transparent;
color: #fff;
}
// padding-top: 10px;
}
textarea::-webkit-input-placeholder {
/* WebKit browsers */
color: #d6d9df;
}
textarea:-moz-placeholder {
/* Mozilla Firefox 4 to 18 */
color: #d6d9df;
}
textarea::-moz-placeholder {
/* Mozilla Firefox 19+ */
color: #d6d9df;
}
textarea::-ms-input-placeholder {
/* Internet Explorer 10+ */
color: #d6d9df;
}
</style>
<style lang="scss">
.itemAMaxBox {
.selectBox {
color: #b0b3be;
.el-select {
.el-input__inner {
border: 1px solid #3768b3;
background: #132550;
border-radius: 4px 4px 0 0;
color: #fff;
}
}
}
}
</style>
<template>
<div class="PagerP1Box" style="pointer-events: auto" v-interact>
<div class="PagerP1TitleBox jcsb">
<div class="left ml8">
<img src="../assets/images/mount/mount_head.png" />
<div class="cp">{{ title }}</div>
</div>
<div class="cp close mr16" @click="close">{{ exit }}</div>
</div>
<div class="PagerP1AreaBox">
<div class="leftArea">
<AngleControl :volume="volume" :rotate="angle" />
</div>
<div class="rightArea">
<div class="w329 h231 mt17 rightAreaBox">
<div class="jcsb h24 tc lh24">
<div
v-for="item in ItemList"
:key="item.id"
class="w160"
:class="type == item.name ? 'active' : 'rightAreaNav'"
@click="type = item.name"
>
{{ item.title }}
</div>
</div>
<div>
<component :is="type" @playAudio="playAudio" />
</div>
</div>
</div>
</div>
</div>
</template>
<script>
import MavLink20Processor from './utils/mavlink20_processor';
import AngleControl from './components/angleControl'; // p1喊话器
import ItemA from './components/itemA'; // 文字转语音
import ItemB from './components/itemB'; // 语音广播
import ItemC from './components/itemC'; // 音频文件
// 必须引入的核心,换成require也是一样的。注意:recorder-core会自动往window下挂载名称为Recorder对象,全局可调用window.Recorder,也许可自行调整相关源码清除全局污染
import Recorder from 'recorder-core';
import { mapGetters } from 'vuex';
const { VUE_APP_FCMQTT_URL } = process.env;
// 需要使用到的音频格式编码引擎的js文件统统加载进来
import 'recorder-core/src/engine/mp3';
import 'recorder-core/src/engine/mp3-engine';
import 'recorder-core/src/engine/pcm';
import mqtt from 'mqtt';
export default {
// watch: {
// 'PoliceKeyCode': {
// handler(value) {
// if(value){
// this.key = value;
// }
// this.init();
// },
// deep: true,
// immediate:true
// },
// },
components: {
AngleControl,
ItemA,
ItemB,
ItemC
},
props: {
title: {
default: '喊话器',
type: String
},
exit: {
default: '关闭',
type: String
},
PoliceKeyCode: {
default: 'MMC301R22205057',
type: String
}
},
data() {
return {
type: 'ItemA',
music: {
list: []
},
// ttsState: null,
key: 'PoliceF737',
ItemList: [
{
id: 1,
name: 'ItemA',
title: '文字转语音'
},
{
id: 2,
name: 'ItemB',
title: '语音广播'
},
{
id: 3,
name: 'ItemC',
title: '音频文件'
}
],
mqtt: {
client: null,
decoder: null,
encoder: new TextEncoder()
},
ttsState: null,
recodeState: null,
volume: 0,
angle: null,
ttsCycle: null,
recodeCycle: null
};
},
provide() {
return {
PagerP1: this,
PoliceKey: () => this.PoliceKeyCode
};
},
computed: {
...mapGetters(['user_info'])
},
mounted() {
this.init();
},
methods: {
playAudio(val) {
this.$emit('playAudio', val);
},
init() {
const url = VUE_APP_FCMQTT_URL;
// let url = 'ws://200.10.1.245:8883/mqtt'
console.log('测试开始连接');
this.mqtt.client = mqtt.connect(url, {
protocol: 'mqtt',
clientId: 3587
});
this.mqtt.client.on('connect', () => {
console.log('mqtt is connected');
});
this.mqtt.client.on('reconnect', function (reconnect) {
console.log(reconnect, 'reconnect');
});
const key = this.PoliceKeyCode;
const topic = 'SPEAK/RECEIVE/${key}-01';
console.log(topic, '链接主题');
this.subscribe(`SPEAK/RECEIVE/${key}-01`, () => {
console.log(`订阅无人机数据:topic:${topic}`);
});
const music_list = [];
this.mqtt.client.on('message', (topic, payload, packet) => {
const data = JSON.parse(packet.payload.toString());
console.log(data, 'musicdata');
this.music.list = data.musicList;
this.ttsState = data.ttsState;
this.recodeState = data.recodeState;
this.volume = data.status_info.volume || 0;
this.angle = data.angle;
this.ttsCycle = data.ttsCycle;
this.recodeCycle = data.recodeCycle;
});
},
subscribe(topic, callback) {
if (!topic) {
return topic;
}
const { client } = this.mqtt;
if (client) {
console.log('订阅数据a', topic);
client.subscribe(topic, callback);
}
},
close() {
this.$emit('close');
this.mqtt.client.end();
this.mqtt.client = null;
}
}
};
</script>
<style lang="scss" scoped>
.PagerP1Box {
position: fixed;
// top: 70px;
top: 300px;
right: 70px;
box-sizing: border-box;
padding: 10px 20px;
width: 510px;
min-height: 296px;
.PagerP1TitleBox {
height: 32px;
line-height: 32px;
background: linear-gradient(180deg, #9198ff 0%, rgba(45, 81, 153, 0.45) 40%, #05091a 100%);
box-shadow: inset 0px 0px 10px 2px #3f9dff;
border-radius: 10px 10px 0px 0px;
border: 1px solid #427dff;
.left {
display: flex;
.cp {
font-size: 20px;
font-family: YouSheBiaoTiHei;
color: #14faff;
line-height: 26px;
text-shadow: 0px 1px 1px rgba(2, 32, 56, 0.2);
background: linear-gradient(
135deg,
#e3aa77 0%,
#f5cda9 38%,
#f9ecd3 58%,
#fcdbb1 79%,
#edb07a 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}
}
.close {
font-size: 14px;
font-family: MicrosoftYaHei;
color: #d2dfff;
}
}
.PagerP1AreaBox {
display: flex;
// justify-content: space-around;
height: 292px;
background: rgba(24, 39, 76, 0.7);
.leftArea {
// width: 204px;
}
.rightArea {
// width: calc(100% - 204px);
// background-color:aquamarine
.rightAreaBox {
// border-radius: 4px 4px 0 0;
.rightAreaNav {
border: 1px solid #3768b3;
background: rgba(23, 70, 216, 0.3);
// box-shadow: 0px 1px 3px 0px rgba(23, 33, 60, 0.5),
// inset 0px 0px 10px 0px rgba(33, 137, 255, 0.4),
// inset 0px 0px 3px 0px #00a7ff;
border: 1px solid;
border-image: linear-gradient(180deg, rgba(138, 218, 255, 1), rgba(82, 179, 255, 0)) 1 1;
font-size: 12px;
font-family: MicrosoftYaHei;
color: #44c5fd;
}
.active {
background: #2647ee;
box-shadow: 0 2px 4px 0 rgba(23, 33, 60, 0.5), inset 0 0 4px 0 #00a7ff,
inset 0 0 16px 0 rgba(33, 137, 255, 0.4);
cursor: pointer;
font-size: 12px;
font-family: MicrosoftYaHei;
color: #ffffff;
}
}
}
}
}
</style>
import jspack from 'jspack';
import Mavlink20 from './mavlink20';
class CmdReadFileList extends Mavlink20 {
format = '<BBB100s';
msg_id = 100100;
order_map = [0, 1, 2, 3];
crc_extra = 250;
name = 'CMD_READ_FILE_LIST';
sum = 0;
id = 0;
// 0 背景音, 1 录音, 2 实时语音, 3 TTS, 4 缓存文件, 5
channel = 0;
constructor(channel = 1, id = 0, sum = 0, name = 'CMD_READ_FILE_LIST') {
super()
this.channel = channel
this.id = id
this.sum = sum
this.name = name
}
pack() {
return super.pack(this, this.crc_extra, jspack.Pack(this.format, [this.channel, this.id, this.sum, this.name]))
}
}
export default CmdReadFileList
\ No newline at end of file
import jspack from 'jspack';
import Mavlink20 from './mavlink20';
class CmdRecordName extends Mavlink20 {
format = '<B100A';
msg_id = 100094;
order_map = [0, 1];
crc_extra = 224;
srcSystem = 255;
srcComponent = 190;
name = 'CMD_RECORD_NAME';
result = null;
constructor(text, format) {
super()
this.text = text
this.format = format
}
pack() {
return super.pack(this, this.crc_extra, jspack.Pack(this.format, [this.result, this.text]))
}
}
export default CmdRecordName
\ No newline at end of file
import jspack from 'jspack';
import Mavlink20 from './mavlink20';
class CmdRecordState extends Mavlink20 {
format = '<BB';
msg_id = 100095;
order_map = [0, 1];
crc_extra = 132;
// srcSystem = 255;
// srcComponent = 190;
state = 11
name = 'CMD_RECORD_STATE';
result = null;
constructor(state) {
super()
this.state = state
}
pack() {
return super.pack(this, this.crc_extra, jspack.Pack(this.format, [this.state, this.result]))
}
}
export default CmdRecordState
\ No newline at end of file
import jspack from 'jspack';
import Mavlink20 from './mavlink20';
class CmdSaveFile extends Mavlink20 {
format = '<BB100A';
msg_id = 100103;
order_map = [0, 1, 2];
crc_extra = 49;
name = 'CMD_SAVE_FILE';
channel = null;
result = null;
filename = "";
constructor(channel, filename, result) {
super()
this.channel = channel
this.filename = filename
}
pack() {
return super.pack(this, this.crc_extra, jspack.Pack(this.format, [this.channel, this.result, this.filename]))
}
}
export default CmdSaveFile
\ No newline at end of file
import jspack from 'jspack';
import Mavlink20 from './mavlink20';
class CmdServoAngle extends Mavlink20 {
format = "<BB";
msg_id = 100112;
order_map = [0, 1];
crc_extra = 33;
name = "CMD_SERVO_ANGLE"
// 0 ~ 60
angle = 0;
result = null;
constructor(angle) {
super()
this.angle = angle
}
pack() {
return super.pack(this, this.crc_extra, jspack.Pack(this.format, [this.angle, this.result]))
}
}
export default CmdServoAngle
\ No newline at end of file
import jspack from 'jspack';
import Mavlink20 from './mavlink20';
class CmdSetSystemVolume extends Mavlink20 {
format = '<BB';
msg_id = 100113;
order_map = [0, 1];
crc_extra = 144;
name = 'CMD_SET_SYSTEM_VOLUME';
result = null;
constructor(volume = 100) {
super()
this.volume = volume
}
pack() {
return super.pack(this, this.crc_extra, jspack.Pack(this.format, [this.volume, this.result]))
}
}
export default CmdSetSystemVolume
\ No newline at end of file
import jspack from 'jspack';
import Mavlink20 from './mavlink20';
// mavlink20.GPI_MEDIA_STREAM_UPLOAD_START = 10 // 流上传开始
// mavlink20.GPI_MEDIA_STREAM_UPLOAD_STOP = 11 // 流上传停止
class CmdStreamFunction extends Mavlink20 {
format = '<BBB';
msg_id = 100097;
order_map = [0, 1, 2];
crc_extra = 109;
name = 'CMD_STREAM_FUNCTION';
func = 0;
type = 0;
result = null;
constructor(func, type, result) {
super()
this.func = func
this.type = type
}
pack() {
return super.pack(this, this.crc_extra, jspack.Pack(this.format, [this.func, this.type, this.result]))
}
}
export default CmdStreamFunction
\ No newline at end of file
import jspack from 'jspack';
import Mavlink20 from './mavlink20';
class CmdStreamUpData extends Mavlink20 {
format = '<B250A';
msg_id = 100098;
order_map = [0, 1];
crc_extra = 14;
name = 'CMD_STREAM_UP_DATA';
constructor(len, data) {
super()
this.len = len
this.data = data
}
pack() {
return super.pack(this, this.crc_extra, jspack.Pack(this.format, [this.len, this.data]))
}
}
export default CmdStreamUpData
\ No newline at end of file
import jspack from 'jspack';
import Mavlink20 from './mavlink20';
class CmdTts extends Mavlink20 {
msg_id = 100085;
order_map = [0, 1];
crc_extra = 253;
name = 'CMD_TTS_TEXT';
result = null;
text;
constructor(text, format = '<B250s') {
super()
this.text = text
this.format = format
}
pack() {
return super.pack(this, this.crc_extra, jspack.Pack(this.format, [this.result, this.text]))
}
}
export default CmdTts
// let tts = new CmdTts("hello world")
// // console.log("tts:", tts);
// console.log("tts:", tts.pack());
\ No newline at end of file
import jspack from 'jspack';
import Mavlink20Header from './mavlink20_header';
class Mavlink20 {
header;
payload;
static HEADER_LEN = 10;
static x25Crc(buffer, crcIN) {
let bytes = buffer;
let crcOUT = crcIN || 0xffff;
bytes.forEach(e => {
let tmp = e ^ (crcOUT & 0xff);
tmp = (tmp ^ (tmp << 4)) & 0xff;
crcOUT = (crcOUT >> 8) ^ (tmp << 8) ^ (tmp << 3) ^ (tmp >> 4);
crcOUT = crcOUT & 0xffff;
})
return crcOUT
}
pack(mav, crc_extra, payload) {
this.payload = payload;
let plen = this.payload.length;
//in MAVLink2 we can strip trailing zeros off payloads. This allows for simple
// variable length arrays and smaller packets
while (plen > 1 && this.payload[plen - 1] == 0) {
plen = plen - 1;
}
this.payload = this.payload.slice(0, plen);
let incompat_flags = 0;
this.header = new Mavlink20Header(this.msg_id, this.payload.length, mav.seq, mav.srcSystem, mav.srcComponent, incompat_flags, 0);
this.msgbuf = this.header.pack().concat(this.payload);
let crc = Mavlink20.x25Crc(this.msgbuf.slice(1));
// For now, assume always using crc_extra = True. TODO: check/fix this.
crc = Mavlink20.x25Crc([crc_extra], crc);
this.msgbuf = this.msgbuf.concat(jspack.Pack('<H', [crc]));
return this.msgbuf;
}
}
export default Mavlink20
\ No newline at end of file
class Mavlink20BadData {
id = -1;
constructor(data, reason) {
this.data = data;
this.reason = reason;
this.msgbuf = data;
}
}
export default Mavlink20BadData
\ No newline at end of file
import jspack from 'jspack';
class Mavlink20Header {
msgId;
mlen = 0;
incompat_flags = 0;
compat_flags = 0;
seq = 0;
srcSystem = 0;
srcComponent = 0;
constructor(msgId, mlen = 0, seq = 0, srcSystem = 0, srcComponent = 0) {
this.msgId = msgId
this.mlen = mlen
this.seq = seq
this.srcSystem = srcSystem
this.srcComponent = srcComponent
}
pack() {
return jspack.Pack('BBBBBBBHB', [253, this.mlen, this.incompat_flags, this.compat_flags, this.seq, this.srcSystem, this.srcComponent, ((this.msgId & 0xFF) << 8) | ((this.msgId >> 8) & 0xFF), this.msgId >> 16]);
}
}
export default Mavlink20Header
\ No newline at end of file
import CmdReadFileList from './cmd_read_file_list';
export default {
100100: { format: '<BBB100A', type: CmdReadFileList, order_map: [0, 1, 2, 3], crc_extra: 250 },
}
/*
* @Author: xiuquanxu
* @Company: kaochong
* @Date: 2020-03-30 22:47:07
* @LastEditors: xiuquanxu
* @LastEditTime: 2021-05-20 16:25:18
*
*
* from: https://github.com/this-spring/pcm-recorder-player
*/
function PcmRecorder(config, cb) {
if (!config) {
config = {
sampleBites: 16,
sampleRate: (new (window.AudioContext
|| window.webkitAudioContext)()).sampleRate,
numberChannels: 1,
fftSize: 512,
down: true,
debug: true,
}
}
this.config = config;
this.recorder = null;
this.analyser = null;
this.audioInput = null; //
this.context = null; // AudioContext对象
this.recorder = null; // 音频输入对象
this.pcmBuffer = [];
this.pcmBufferSize = 0;
this.visualVolume = 0;
this.cb = cb;
this.init();
}
PcmRecorder.prototype.getVolume = function () {
return this.visualVolume;
}
PcmRecorder.prototype.start = function () {
var _this = this;
navigator.mediaDevices.getUserMedia({
audio: true,
}).then((stream) => {
_this.audioInput = _this.context.createMediaStreamSource(stream);
}, (error) => {
console.error(error);
}).then(() => {
_this.audioInput.connect(_this.analyser);
_this.analyser.connect(_this.recorder);
_this.recorder.connect(_this.context.destination);
});
}
PcmRecorder.prototype.stop = function () {
if (this.audioInput) this.audioInput.disconnect();
if (this.recorder) this.recorder.disconnect();
}
PcmRecorder.prototype.init = function () {
this.context = new (window.AudioContext || window.webkitAudioContext)();
this.analyser = this.context.createAnalyser(); // 录音分析节点
// this.analyser.fftSize = this.context.sampleRate / 100;
this.analyser.fftSize = this.config.fftSize;
// pcmNode
const createScript = this.context.createScriptProcessor || this.context.createJavaScriptNode;
// recorder Analyser
this.recorder = createScript.apply(this.context,
[this.config.fftSize, this.config.numberChannels, this.config.numberChannels]);
// 音频采集
this.recorder.onaudioprocess = this.onaudioprocess.bind(this)
}
PcmRecorder.prototype.onaudioprocess = function (e) {
if (this.config.numberChannels === 1) {
const data = e.inputBuffer.getChannelData(0);
console.log(data.length);
this.cb && this.cb(data)
}
}
export default PcmRecorder
\ No newline at end of file
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论