设备控制
parent
162cd01b8a
commit
b68548ddd2
14
pages.json
14
pages.json
|
|
@ -31,6 +31,11 @@
|
||||||
"navigationBarTitleText": "示例"
|
"navigationBarTitleText": "示例"
|
||||||
}
|
}
|
||||||
}, {
|
}, {
|
||||||
|
"path": "pages/control/index",
|
||||||
|
"style": {
|
||||||
|
"navigationBarTitleText": "控制中心"
|
||||||
|
}
|
||||||
|
},{
|
||||||
"path": "pages/mine/avatar/index",
|
"path": "pages/mine/avatar/index",
|
||||||
"style": {
|
"style": {
|
||||||
"navigationBarTitleText": "修改头像"
|
"navigationBarTitleText": "修改头像"
|
||||||
|
|
@ -86,7 +91,14 @@
|
||||||
"iconPath": "static/images/tabbar/home.png",
|
"iconPath": "static/images/tabbar/home.png",
|
||||||
"selectedIconPath": "static/images/tabbar/home_.png",
|
"selectedIconPath": "static/images/tabbar/home_.png",
|
||||||
"text": "首页"
|
"text": "首页"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
|
"pagePath": "pages/control/index",
|
||||||
|
"iconPath": "static/images/tabbar/work.png",
|
||||||
|
"selectedIconPath": "static/images/tabbar/work_.png",
|
||||||
|
"text": "控制中心"
|
||||||
|
},
|
||||||
|
{
|
||||||
"pagePath": "pages/work/index",
|
"pagePath": "pages/work/index",
|
||||||
"iconPath": "static/images/tabbar/work.png",
|
"iconPath": "static/images/tabbar/work.png",
|
||||||
"selectedIconPath": "static/images/tabbar/work_.png",
|
"selectedIconPath": "static/images/tabbar/work_.png",
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,665 @@
|
||||||
|
<!--
|
||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<view class="header">
|
||||||
|
<text class="title">控制中心</text>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<uni-section title="设备【864536071808560】" titleFontSize="16px" type="line" >
|
||||||
|
<uni-card :is-shadow="true">
|
||||||
|
<uni-list :border="false">
|
||||||
|
<uni-list-item title="卷被开" direction="row" note="暂停" :show-switch="true" @switchChange="switchChange">
|
||||||
|
</uni-list-item>
|
||||||
|
</uni-list>
|
||||||
|
</uni-card>
|
||||||
|
|
||||||
|
<uni-card :border="false" padding="20rpx" @click="handleCardClick('jbk')">
|
||||||
|
<template v-slot:content>
|
||||||
|
<view class="card-content">
|
||||||
|
<view class="card-text">
|
||||||
|
<text class="card-main">卷被开</text>
|
||||||
|
<text class="card-sub">{{ show.jbk }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="card-icon" :class="{ active: status.jbk === '运行' }">
|
||||||
|
<uni-icons :type=" (status.jbk === '运行')?'circle':'circle-filled'" size="24" color="#fff" />
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
</uni-card>
|
||||||
|
</uni-section>
|
||||||
|
|
||||||
|
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import mqtt from 'mqtt'
|
||||||
|
import UniList from "../../uni_modules/uni-list/components/uni-list/uni-list.vue";
|
||||||
|
import UniListItem from "../../uni_modules/uni-list/components/uni-list-item/uni-list-item.vue";
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {UniListItem, UniList},
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
mqttConfig: {
|
||||||
|
host: '1.94.254.176',
|
||||||
|
port: 9001,
|
||||||
|
clientId: 'uniapp_mqtt_' + Math.random().toString(16).substr(2, 8),
|
||||||
|
username: 'admin',
|
||||||
|
password: 'Admin#12345678',
|
||||||
|
subscribeTopic: 'test/topic'
|
||||||
|
},
|
||||||
|
plain:true,
|
||||||
|
publishTopic: 'test/topic',
|
||||||
|
message: '',
|
||||||
|
client: null,
|
||||||
|
connected: false,
|
||||||
|
messages: [],
|
||||||
|
border:true,
|
||||||
|
cover: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/shuijiao.jpg',
|
||||||
|
avatar: 'https://qiniu-web-assets.dcloud.net.cn/unidoc/zh/unicloudlogo.png',
|
||||||
|
extraIcon:{
|
||||||
|
color: '#4cd964',
|
||||||
|
size: '22',
|
||||||
|
type: 'gear-filled'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
onClick(e){
|
||||||
|
console.log(e)
|
||||||
|
},
|
||||||
|
actionsClick(text){
|
||||||
|
uni.showToast({
|
||||||
|
title:text,
|
||||||
|
icon:'none'
|
||||||
|
})
|
||||||
|
},
|
||||||
|
connectMqtt() {
|
||||||
|
const options = {
|
||||||
|
clientId: this.mqttConfig.clientId,
|
||||||
|
username: this.mqttConfig.username,
|
||||||
|
password: this.mqttConfig.password,
|
||||||
|
clean: true,
|
||||||
|
connectTimeout: 4000,
|
||||||
|
reconnectPeriod: 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = `ws://${this.mqttConfig.host}:${this.mqttConfig.port}/mqtt`
|
||||||
|
|
||||||
|
this.client = mqtt.connect(url, options)
|
||||||
|
|
||||||
|
this.client.on('connect', () => {
|
||||||
|
this.connected = true
|
||||||
|
this.addMessage('已连接到MQTT服务器')
|
||||||
|
this.client.subscribe(this.mqttConfig.subscribeTopic, (err) => {
|
||||||
|
if (!err) {
|
||||||
|
this.addMessage(`已订阅主题: ${this.mqttConfig.subscribeTopic}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
this.client.on('message', (topic, payload) => {
|
||||||
|
this.addMessage(`收到消息 [${topic}]: ${payload.toString()}`)
|
||||||
|
})
|
||||||
|
|
||||||
|
this.client.on('error', (err) => {
|
||||||
|
this.addMessage(`连接错误: ${err.message}`)
|
||||||
|
this.connected = false
|
||||||
|
})
|
||||||
|
|
||||||
|
this.client.on('reconnect', () => {
|
||||||
|
this.addMessage('正在重新连接...')
|
||||||
|
})
|
||||||
|
|
||||||
|
this.client.on('close', () => {
|
||||||
|
this.addMessage('连接已关闭')
|
||||||
|
this.connected = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
disconnectMqtt() {
|
||||||
|
if (this.client) {
|
||||||
|
this.client.end()
|
||||||
|
this.connected = false
|
||||||
|
this.addMessage('已断开MQTT连接')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
publishMessage() {
|
||||||
|
if (!this.connected) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请先连接MQTT服务器',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.publishTopic || !this.message) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '请填写主题和消息内容',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client.publish(this.publishTopic, this.message, (err) => {
|
||||||
|
if (!err) {
|
||||||
|
this.addMessage(`已发布消息到 [${this.publishTopic}]: ${this.message}`)
|
||||||
|
this.message = ''
|
||||||
|
} else {
|
||||||
|
this.addMessage(`发布失败: ${err.message}`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
addMessage(content) {
|
||||||
|
this.messages.unshift({
|
||||||
|
time: new Date().toLocaleTimeString(),
|
||||||
|
content: content
|
||||||
|
})
|
||||||
|
},
|
||||||
|
switchChange() {
|
||||||
|
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.client) {
|
||||||
|
this.client.end()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped lang="scss">
|
||||||
|
$uni-success: #18bc37 !default;
|
||||||
|
.container {
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
min-height: 100vh;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
text-align: center;
|
||||||
|
padding: 40rpx 0;
|
||||||
|
background-color: #007AFF;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
font-size: 36rpx;
|
||||||
|
font-weight: bold;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-section {
|
||||||
|
background-color: white;
|
||||||
|
border-radius: 10rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
box-shadow: 0 2rpx 10rpx rgba(0,0,0,0.1);
|
||||||
|
}
|
||||||
|
.button-group {
|
||||||
|
margin-top: 15px;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
.example-body {
|
||||||
|
/* #ifndef APP-NVUE */
|
||||||
|
display: block;
|
||||||
|
/* #endif */
|
||||||
|
padding: 10px;
|
||||||
|
}
|
||||||
|
.decoration {
|
||||||
|
width: 8px;
|
||||||
|
height: 8px;
|
||||||
|
margin-right: 4px;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: $uni-success;
|
||||||
|
}
|
||||||
|
.container {
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.custom-cover {
|
||||||
|
flex: 1;
|
||||||
|
flex-direction: row;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cover-content {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 0;
|
||||||
|
left: 0;
|
||||||
|
right: 0;
|
||||||
|
height: 40px;
|
||||||
|
background-color: rgba($color: #000000, $alpha: 0.4);
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
padding-left: 15px;
|
||||||
|
font-size: 14px;
|
||||||
|
color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-actions {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-around;
|
||||||
|
align-items: center;
|
||||||
|
height: 45px;
|
||||||
|
border-top: 1px #eee solid;
|
||||||
|
}
|
||||||
|
.card-actions-item {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.card-actions-item-text {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #666;
|
||||||
|
margin-left: 5px;
|
||||||
|
}
|
||||||
|
.cover-image {
|
||||||
|
flex: 1;
|
||||||
|
height: 150px;
|
||||||
|
}
|
||||||
|
.no-border {
|
||||||
|
border-width: 0;
|
||||||
|
}
|
||||||
|
</style>-->
|
||||||
|
<template>
|
||||||
|
<view class="container">
|
||||||
|
<!-- 控制设置标题 -->
|
||||||
|
<view class="control-title">控制设置</view>
|
||||||
|
<uni-section :title="title" titleFontSize="16px" type="line">
|
||||||
|
|
||||||
|
<!-- 卷膜/卷被卡片容器(2列栅格布局) -->
|
||||||
|
<view class="card-grid">
|
||||||
|
<!-- 卷被开卡片 -->
|
||||||
|
<view class="control-card" @click="handleCardClick(1-status.jbk, 'jbk')">
|
||||||
|
<view class="card-text">
|
||||||
|
<text class="card-main">卷被开</text>
|
||||||
|
<text class="card-sub">{{ show.jbk }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="card-icon" :class="{ active: status.jbk === '运行' }">
|
||||||
|
<uni-icons :type=" (status.jbk === '运行')?'circle':'circle-filled'" size="24" color="#fff"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 卷被关卡片 -->
|
||||||
|
<view class="control-card" @click="handleCardClick(1-status.jbg,'jbg')">
|
||||||
|
<view class="card-text">
|
||||||
|
<text class="card-main">卷被关</text>
|
||||||
|
<text class="card-sub">{{ show.jbg }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="card-icon" :class="{ active: status.jbg === '运行' }">
|
||||||
|
<uni-icons :type=" (status.jbg === '运行')?'circle':'circle-filled'" size="24" color="#fff"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 卷膜1开卡片 -->
|
||||||
|
<view class="control-card" @click="handleCardClick(1-status.jm1k, 'jm1k')">
|
||||||
|
<view class="card-text">
|
||||||
|
<text class="card-main">卷膜1开</text>
|
||||||
|
<text class="card-sub">{{ show.jm1k }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="card-icon" :class="{ active: status.jm1k === '运行' }">
|
||||||
|
<uni-icons :type="(status.jm1k === '运行')?'circle':'circle-filled'" size="24" color="#fff"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 卷膜1关卡片 -->
|
||||||
|
<view class="control-card" @click="handleCardClick(1-status.jm1g, 'jm1g')">
|
||||||
|
<view class="card-text">
|
||||||
|
<text class="card-main">卷膜1关</text>
|
||||||
|
<text class="card-sub">{{ show.jm1g }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="card-icon" :class="{ active: status.jm1g === '运行' }">
|
||||||
|
<uni-icons :type="(status.jm1g === '运行')?'circle':'circle-filled'" size="24" color="#fff"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 卷膜2卡片 -->
|
||||||
|
<view class="control-card" @click="handleCardClick(1-status.jm2k, 'jm2k')">
|
||||||
|
<view class="card-text">
|
||||||
|
<text class="card-main">卷膜2开</text>
|
||||||
|
<text class="card-sub">{{ show.jm2k }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="card-icon" :class="{ active: status.jm2k === '运行' }">
|
||||||
|
<uni-icons :type="(status.jm2k === '运行')?'circle':'circle-filled'" size="24" color="#fff"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 卷膜2关卡片 -->
|
||||||
|
<view class="control-card" @click="handleCardClick(1-status.jm2g, 'jm2g')">
|
||||||
|
<view class="card-text">
|
||||||
|
<text class="card-main">卷膜2关</text>
|
||||||
|
<text class="card-sub">{{ show.jm2g }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="card-icon" :class="{ active: status.jm2g === '运行' }">
|
||||||
|
<uni-icons :type="(status.jm2g === '运行')?'circle':'circle-filled'" size="24" color="#fff"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
<!-- 卷膜3开卡片 -->
|
||||||
|
<view class="control-card" @click="handleCardClick(1-status.jm3k, 'jm3k')">
|
||||||
|
<view class="card-text">
|
||||||
|
<text class="card-main">卷膜3开</text>
|
||||||
|
<text class="card-sub">{{ show.jm3k }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="card-icon" :class="{ active: status.jm3k === '运行' }">
|
||||||
|
<uni-icons :type="(status.jm3k === '运行')?'circle':'circle-filled'" size="24" color="#fff"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
|
||||||
|
<!-- 卷膜3关卡片 -->
|
||||||
|
<view class="control-card" @click="handleCardClick(1-status.jm3g, 'jm3g')">
|
||||||
|
<view class="card-text">
|
||||||
|
<text class="card-main">卷膜3关</text>
|
||||||
|
<text class="card-sub">{{ show.jm3g }}</text>
|
||||||
|
</view>
|
||||||
|
<view class="card-icon" :class="{ active: status.jm3g === '运行' }">
|
||||||
|
<uni-icons :type="(status.jm3g === '运行')?'circle':'circle-filled'" size="24" color="#fff"/>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</view>
|
||||||
|
</uni-section>
|
||||||
|
</view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import mqtt from 'mqtt'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
mqttConfig: {
|
||||||
|
host: '1.94.254.176',
|
||||||
|
port: 9001,
|
||||||
|
clientId: 'uniapp_mqtt_' + Math.random().toString(16).substr(2, 8),
|
||||||
|
username: 'admin',
|
||||||
|
password: 'Admin#12345678',
|
||||||
|
subscribeTopic:'/up',
|
||||||
|
},
|
||||||
|
imei:'864536071808560',
|
||||||
|
publishTopic: '/down',
|
||||||
|
title:'',
|
||||||
|
message: {},
|
||||||
|
// 卡片状态(模拟后端返回数据)
|
||||||
|
show: {
|
||||||
|
jbk: "暂停",
|
||||||
|
jbg: "暂停",
|
||||||
|
jm1k: "暂停",
|
||||||
|
jm1g: "暂停",
|
||||||
|
jm2k: "暂停",
|
||||||
|
jm2g: "暂停",
|
||||||
|
jm3k: "暂停",
|
||||||
|
jm3g: "暂停"
|
||||||
|
},
|
||||||
|
status: {
|
||||||
|
jbk: 0,
|
||||||
|
jbg: 0,
|
||||||
|
jm1k: 0,
|
||||||
|
jm1g: 0,
|
||||||
|
jm2k: 0,
|
||||||
|
jm2g: 0,
|
||||||
|
jm3k: 0,
|
||||||
|
jm3g: 0
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
onLoad() {
|
||||||
|
this.publishTopic = "dtu/"+this.imei+this.publishTopic;
|
||||||
|
this.subscribeTopic = "dtu/"+this.imei+this.subscribeTopic;
|
||||||
|
this.title="设备【"+this.imei+"】";
|
||||||
|
if (this.status.jbk===1) {
|
||||||
|
this.status.jbg = 0;
|
||||||
|
}
|
||||||
|
if (this.status.jbg===1) {
|
||||||
|
this.status.jbk = 0;
|
||||||
|
}
|
||||||
|
if (this.status.jm1k===1) {
|
||||||
|
this.status.jm1g = 0;
|
||||||
|
}
|
||||||
|
if (this.status.jm2k===1) {
|
||||||
|
this.status.jm2g = 0;
|
||||||
|
}
|
||||||
|
if (this.status.jm3k===1) {
|
||||||
|
this.status.jm3g = 0;
|
||||||
|
}
|
||||||
|
if (this.status.jm1g===1) {
|
||||||
|
this.status.jm1k = 0;
|
||||||
|
}
|
||||||
|
if (this.status.jm2g===1) {
|
||||||
|
this.status.jm2k = 0;
|
||||||
|
}
|
||||||
|
if (this.status.jm2g===1) {
|
||||||
|
this.status.jm3k = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
console.info(this.status)
|
||||||
|
},
|
||||||
|
onUnload() {
|
||||||
|
this.disconnectMqtt()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
|
||||||
|
// 卡片点击事件(实际项目中调用接口修改状态) 功能标识
|
||||||
|
handleCardClick(status, type) {
|
||||||
|
uni.showModal({
|
||||||
|
title: '操作提示:',
|
||||||
|
content: '确定'+(status===1?"运行":"暂停")+'设备?',
|
||||||
|
cancelText: '取消',
|
||||||
|
confirmText: '确定',
|
||||||
|
success: (res) =>{
|
||||||
|
console.info("操作功能:【"+type+"】,变更状态为:"+ status)
|
||||||
|
// 链接mqtt
|
||||||
|
this.connectMqtt()
|
||||||
|
// 组装消息
|
||||||
|
this.message = JSON.stringify({[type]: status})
|
||||||
|
console.info("指令:"+this.message)
|
||||||
|
// 控制设备
|
||||||
|
this.publishMessage();
|
||||||
|
// // 设备回执
|
||||||
|
this.ackMessage(type);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
console.info(this.status)
|
||||||
|
},
|
||||||
|
connectMqtt() {
|
||||||
|
const options = {
|
||||||
|
clientId: this.mqttConfig.clientId,
|
||||||
|
username: this.mqttConfig.username,
|
||||||
|
password: this.mqttConfig.password,
|
||||||
|
clean: true,
|
||||||
|
connectTimeout: 4000,
|
||||||
|
reconnectPeriod: 1000
|
||||||
|
}
|
||||||
|
|
||||||
|
const url = `ws://${this.mqttConfig.host}:${this.mqttConfig.port}/mqtt`
|
||||||
|
|
||||||
|
this.client = mqtt.connect(url, options)
|
||||||
|
|
||||||
|
this.client.on('connect', () => {
|
||||||
|
this.connected = true
|
||||||
|
this.addMessage('已连接到MQTT服务器')
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
this.client.on('error', (err) => {
|
||||||
|
this.addMessage(`控制失败: ${err.message}`)
|
||||||
|
this.connected = false
|
||||||
|
})
|
||||||
|
|
||||||
|
this.client.on('reconnect', () => {
|
||||||
|
this.addMessage('正在重新连接...')
|
||||||
|
})
|
||||||
|
|
||||||
|
this.client.on('close', () => {
|
||||||
|
this.addMessage('连接已关闭')
|
||||||
|
this.connected = false
|
||||||
|
})
|
||||||
|
},
|
||||||
|
|
||||||
|
disconnectMqtt() {
|
||||||
|
if (this.client) {
|
||||||
|
this.client.end()
|
||||||
|
this.connected = false
|
||||||
|
this.addMessage('已断开MQTT连接')
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
publishMessage() {
|
||||||
|
if (!this.connected || !this.publishTopic || !this.message) {
|
||||||
|
uni.showToast({
|
||||||
|
title: '控制设备失败',
|
||||||
|
icon: 'none'
|
||||||
|
})
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
this.client.publish(this.publishTopic, this.message, (err) => {
|
||||||
|
if (!err) {
|
||||||
|
this.addMessage(`【指令已发送】imei: ${this.publishTopic},指令: ${this.message}`);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
this.addMessage(`发布失败: ${err.message},设备:[${this.publishTopic}]`)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.message = {};
|
||||||
|
},
|
||||||
|
|
||||||
|
ackMessage(type) {
|
||||||
|
this.client.on("message", (topic, payload) => {
|
||||||
|
// 1. 先判断是否是目标订阅主题(如dtu/xxx/up)
|
||||||
|
if (topic !== this.status.subscribeTopic) return;
|
||||||
|
|
||||||
|
// 2. 解析消息体(注意异常捕获)
|
||||||
|
let msgData = {};
|
||||||
|
try {
|
||||||
|
msgData = JSON.parse(payload.toString());
|
||||||
|
} catch (e) {
|
||||||
|
console.error("消息解析失败:", e);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 3. 区分“回执”和“其他内容”
|
||||||
|
if (msgData.prop && "suc" in msgData) {
|
||||||
|
// 👉 这是“指令回执”
|
||||||
|
this.handleCommandAck(msgData,type);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
addMessage(content) {
|
||||||
|
|
||||||
|
console.info("提示消息:"+content)
|
||||||
|
},
|
||||||
|
switchChange() {
|
||||||
|
|
||||||
|
},
|
||||||
|
// 处理指令回执的函数
|
||||||
|
handleCommandAck(ackData,type) {
|
||||||
|
// 拿到指令字段(如jm2k)和执行状态(suc)
|
||||||
|
const commandField = Object.keys(ackData.prop)[0]; // 这里是"jm2k"
|
||||||
|
const commandValue = ackData.prop[commandField]; // 这里是0
|
||||||
|
const isSuccess = ackData.suc; // 这里是true
|
||||||
|
|
||||||
|
if (isSuccess) {
|
||||||
|
this.status[type] = this.status[type] === 0 ? 1 : 0;
|
||||||
|
this.show[type] = this.status[type] === 0 ? "运行" : "暂停";
|
||||||
|
}
|
||||||
|
// 业务逻辑:提示“指令执行成功/失败”
|
||||||
|
console.log(`指令[${commandField}=${commandValue}]执行${isSuccess ? "成功" : "失败"}`);
|
||||||
|
// (可匹配之前发布的指令msgId,更新UI状态)
|
||||||
|
},
|
||||||
|
|
||||||
|
// 处理其他内容的函数
|
||||||
|
handleOtherContent(otherData) {
|
||||||
|
// 业务逻辑:处理传感器数据、设备状态等
|
||||||
|
console.log("收到其他内容:", otherData);
|
||||||
|
// 例如:更新温湿度显示、设备在线状态等
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
beforeDestroy() {
|
||||||
|
if (this.client) {
|
||||||
|
this.client.end()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.container {
|
||||||
|
padding: 20rpx;
|
||||||
|
background-color: #f5f5f5;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 控制设置标题 */
|
||||||
|
.control-title {
|
||||||
|
font-size: 32rpx;
|
||||||
|
font-weight: 500;
|
||||||
|
text-align: center;
|
||||||
|
margin-bottom: 30rpx;
|
||||||
|
color: #333;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 2列栅格布局 */
|
||||||
|
.card-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 1fr 1fr;
|
||||||
|
gap: 20rpx;
|
||||||
|
padding: 20rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片样式 */
|
||||||
|
.control-card {
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 16rpx;
|
||||||
|
padding: 30rpx 20rpx;
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
align-items: center;
|
||||||
|
box-shadow: 0 2rpx 8rpx #bfbec1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片文字区域 */
|
||||||
|
.card-text {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 8rpx;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-main {
|
||||||
|
font-size: 30rpx;
|
||||||
|
color: #333;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
|
||||||
|
.card-sub {
|
||||||
|
font-size: 24rpx;
|
||||||
|
color: #999;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 卡片图标容器 */
|
||||||
|
.card-icon {
|
||||||
|
width: 48rpx;
|
||||||
|
height: 48rpx;
|
||||||
|
border-radius: 50%;
|
||||||
|
background-color: #e5e5e5;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 激活状态(运行) */
|
||||||
|
.card-icon.active {
|
||||||
|
background-color: #007aff;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -66,3 +66,7 @@ export function mqttDisconnect(){
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue