You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
546 lines
16 KiB
546 lines
16 KiB
<template>
|
|
<view class="container">
|
|
<!-- 头部标题 -->
|
|
<!-- <view class="title">STM32智能AI家居系统</view> -->
|
|
<u-navbar class="navbar" title="STM32智能AI家居系统" fixed> </u-navbar>
|
|
<!-- 显示数据部分:温度、湿度、Co2、Tvoc、烟雾浓度、光照强度、是否有人、声光报警状态 -->
|
|
<view class="view-data">
|
|
<!-- 温度 -->
|
|
<view class="view-data-item">
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./wd.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>{{ deviceInfo.temperature || "-" }}<span>°C</span>
|
|
</view>
|
|
</view>
|
|
<!-- 湿度 -->
|
|
<view class="view-data-item">
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./sd.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>{{ deviceInfo.humidity || "-" }}<span>%RH</span>
|
|
</view>
|
|
</view>
|
|
<!-- Co2 -->
|
|
<view class="view-data-item">
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./CO2.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>{{ deviceInfo.Co2 || "-" }}<span>ppm</span>
|
|
</view>
|
|
</view>
|
|
<!-- Tvoc -->
|
|
<view class="view-data-item">
|
|
<view class="data-item-img-box">
|
|
<image
|
|
class="data-item-img"
|
|
src="./tvoc-copy.png"
|
|
mode="widthFix"
|
|
></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>{{ deviceInfo.Tvoc || "-" }}<span>ppb</span>
|
|
</view>
|
|
</view>
|
|
<!-- 烟雾浓度 -->
|
|
<view class="view-data-item">
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./ywnd.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>{{ deviceInfo.smoke || "-" }}<span>%LEL</span>
|
|
</view>
|
|
</view>
|
|
<!-- 光照强度 -->
|
|
<view class="view-data-item">
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./gzqd.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>{{ deviceInfo.light || "-" }}<span>Lux</span>
|
|
</view>
|
|
</view>
|
|
<!-- 是否有人 -->
|
|
<view class="view-data-item">
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./sfyr.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text">{{
|
|
deviceInfo.person == 1 ? "有人" : "没人"
|
|
}}</view>
|
|
</view>
|
|
<!-- 声光报警状态 -->
|
|
<view class="view-data-item">
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./sgbj.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>{{ deviceInfo.alarm == 1 ? "报警开启" : "报警关闭" }}<span></span>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<!-- 控制部分 -->
|
|
<view class="control">
|
|
<view class="view-data-item" style="width: 100%">
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./wd.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text">
|
|
LED({{ deviceInfo.LED || "-" }}%)
|
|
<u-slider
|
|
style="width: 100%"
|
|
v-model="deviceInfo.LED"
|
|
min="0"
|
|
max="100"
|
|
:step="20"
|
|
@change="handleAttribute()"
|
|
></u-slider>
|
|
</view>
|
|
</view>
|
|
<view
|
|
class="view-data-item"
|
|
@click="handleCommand('statusMotor', 'curtain')"
|
|
:class="deviceInfo.curtain == 0 ? 'view-filter' : ''"
|
|
>
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./sd.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>窗帘
|
|
<view>{{ deviceInfo.curtain == 0 ? "OFF" : "ON" }}</view>
|
|
</view>
|
|
</view>
|
|
<view
|
|
class="view-data-item"
|
|
@click="handleCommand('statusHumidifier', 'humidifier')"
|
|
:class="deviceInfo.humidifier == 0 ? 'view-filter' : ''"
|
|
>
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./CO2.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>加湿器
|
|
<view>{{ deviceInfo.humidifier == 0 ? "OFF" : "ON" }}</view>
|
|
</view>
|
|
</view>
|
|
<view
|
|
class="view-data-item"
|
|
@click="handleCommand('statusFan', 'fan')"
|
|
:class="deviceInfo.fan == 0 ? 'view-filter' : ''"
|
|
>
|
|
<view class="data-item-img-box">
|
|
<image
|
|
class="data-item-img"
|
|
src="./tvoc-copy.png"
|
|
mode="widthFix"
|
|
></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>风扇
|
|
<view>{{ deviceInfo.fan == 0 ? "OFF" : "ON" }}</view>
|
|
</view>
|
|
</view>
|
|
<view
|
|
class="view-data-item"
|
|
@click="handleCommand('statusAircleaner', 'airCleaner')"
|
|
:class="deviceInfo.airCleaner == 0 ? 'view-filter' : ''"
|
|
>
|
|
<view class="data-item-img-box">
|
|
<image class="data-item-img" src="./ywnd.png" mode="widthFix"></image>
|
|
</view>
|
|
<view class="data-item-text"
|
|
>空气净化器
|
|
<view>{{ deviceInfo.airCleaner == 0 ? "OFF" : "ON" }}</view>
|
|
</view>
|
|
</view>
|
|
</view>
|
|
<!-- 阈值设定部分 -->
|
|
<view class="threshold">
|
|
<u-cell-group>
|
|
<u-cell
|
|
title="光照阈值"
|
|
:value="deviceInfo.lightThreshold"
|
|
isLink
|
|
@click="handleSettingThreshold('lightThreshold', 'lightThreshold')"
|
|
></u-cell>
|
|
<u-cell
|
|
title="湿度下限阈值"
|
|
:value="deviceInfo.humidityLowerThreshold"
|
|
isLink
|
|
@click="
|
|
handleSettingThreshold('humiLowThreshold', 'humiLowThreshold')
|
|
"
|
|
></u-cell>
|
|
<u-cell
|
|
title="湿度上限阈值"
|
|
:value="deviceInfo.humidityUpperThreshold"
|
|
isLink
|
|
@click="
|
|
handleSettingThreshold('humiHighThreshold', 'humiHighThreshold')
|
|
"
|
|
></u-cell>
|
|
<u-cell
|
|
title="空气质量阈值"
|
|
:value="deviceInfo.airQualityThreshold"
|
|
isLink
|
|
@click="handleSettingThreshold('tvocThreshold', 'tvocThreshold')"
|
|
></u-cell>
|
|
</u-cell-group>
|
|
</view>
|
|
</view>
|
|
</template>
|
|
|
|
<script>
|
|
import {
|
|
login,
|
|
queryProjectInfoByKey,
|
|
deviceList,
|
|
attributes,
|
|
sendAttribute,
|
|
sendCommand,
|
|
} from "@/common/api.js";
|
|
export default {
|
|
data() {
|
|
return {
|
|
value: 30,
|
|
deviceId: "", // 设备id
|
|
// 温度、湿度、Co2、Tvoc、烟雾浓度、光照强度、是否有人、声光报警状态
|
|
deviceInfo: {},
|
|
falt: false,
|
|
timer: null,
|
|
};
|
|
},
|
|
|
|
methods: {
|
|
// 跳转到阈值设定页面
|
|
handleSettingThreshold(_name, _valueName) {
|
|
let value = this.deviceInfo[_valueName];
|
|
uni.navigateTo({
|
|
url: `/pages/index/details?name=${_name}&value=${value}&deviceId=${this.deviceId}`,
|
|
}); // 跳转到阈值设定页面
|
|
},
|
|
/** 下发属性 */
|
|
async handleAttribute() {
|
|
const res = await sendAttribute({
|
|
deviceId: this.deviceId, // 设备id
|
|
// 阈值JSON字符串
|
|
attributeAndValues: [
|
|
{
|
|
attributeIdentifier: "statusLed",
|
|
attributeValue: this.deviceInfo.LED,
|
|
},
|
|
],
|
|
});
|
|
const { data, code } = res;
|
|
if (code == 200) {
|
|
this.getAttributes(this.deviceId); // 根据项目id查找设备列表
|
|
// this.$refs.uToast.show({
|
|
// type: "success",
|
|
// message: "操作成功",
|
|
// });
|
|
}
|
|
},
|
|
// 下发命令
|
|
async handleCommand(_name, _valueName) {
|
|
this.deviceInfo[_valueName] = this.deviceInfo[_valueName] == 0 ? 1 : 0;
|
|
let commandParams = { [_name]: this.deviceInfo[_valueName] }; // 0 关闭 1 开启,
|
|
console.log("commandParams", commandParams);
|
|
const res = await sendCommand({
|
|
commandId: "447242774207232", // 命令ID,
|
|
commandParams: JSON.stringify(commandParams), // 命令参数,
|
|
deviceId: this.deviceId,
|
|
});
|
|
const { data, code } = res;
|
|
if (code == 200) {
|
|
this.getAttributes(this.deviceId); // 根据项目id查找设备列表
|
|
}
|
|
},
|
|
// 通过ID查询患者详情
|
|
async handleLogin() {
|
|
this.fileList = [];
|
|
const res = await login({
|
|
code: "3",
|
|
password: "admin123",
|
|
username: "yf_test",
|
|
});
|
|
const { data, code } = res;
|
|
if (code == 200) {
|
|
this.falt = true; // 登录成功后显示数据
|
|
uni.setStorageSync("userToken", data.token);
|
|
this.getqueryProjectInfoByKey();
|
|
}
|
|
},
|
|
// 通过ID查询患者详情
|
|
async getqueryProjectInfoByKey() {
|
|
this.fileList = [];
|
|
const res = await queryProjectInfoByKey({ projectKey: "qKStHKKt" });
|
|
const { data, code } = res;
|
|
if (code == 200) {
|
|
this.getDeviceList(data.id); // 根据项目id查找设备列表
|
|
}
|
|
},
|
|
// 根据项目id查找设备列表
|
|
async getDeviceList(_id) {
|
|
const res = await deviceList({ projectId: _id });
|
|
const { rows, code } = res;
|
|
if (code == 200) {
|
|
const w2Device = rows.find((device) => device.deviceName === "H1");
|
|
this.deviceId = w2Device.id;
|
|
this.getAttributes(this.deviceId); // 根据设备id查找设备信息
|
|
}
|
|
},
|
|
|
|
// 根据设备id查找设备信息
|
|
async getAttributes(_id) {
|
|
const res = await attributes({ deviceId: _id });
|
|
const { data, code } = res;
|
|
if (code == 200) {
|
|
this.loading = false;
|
|
let deviceAttributesList = data.deviceAttributesList;
|
|
// ------ 显示 ------
|
|
// 温度、湿度、Co2、Tvoc、烟雾浓度、光照强度、是否有人、声光报警状态
|
|
// 温度
|
|
let temperature = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969472
|
|
)?.attributeValue;
|
|
// 湿度
|
|
let humidity = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969473
|
|
)?.attributeValue;
|
|
// Co2
|
|
let Co2 = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969475
|
|
)?.attributeValue;
|
|
// Tvoc
|
|
let Tvoc = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969474
|
|
)?.attributeValue;
|
|
// 烟雾浓度
|
|
let smoke = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969476
|
|
)?.attributeValue;
|
|
|
|
// 光照强度
|
|
let light = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969477
|
|
)?.attributeValue;
|
|
// 是否有人
|
|
let person = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969479
|
|
)?.attributeValue;
|
|
// 声光报警状态
|
|
let alarm = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969478
|
|
)?.attributeValue;
|
|
// ------ 开关 ------
|
|
// LED,窗帘开关,加湿器开关,风扇开关,空气净化器开关
|
|
// LED
|
|
let LED = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969480
|
|
)?.attributeValue;
|
|
// 窗帘开关
|
|
let curtain = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969481
|
|
)?.attributeValue;
|
|
// 加湿器开关
|
|
let humidifier = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969482
|
|
)?.attributeValue;
|
|
// 风扇开关
|
|
let fan = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969483
|
|
)?.attributeValue;
|
|
// 空气净化器开关
|
|
let airCleaner = deviceAttributesList.find(
|
|
(row) => row.id === 448053828969484
|
|
)?.attributeValue;
|
|
|
|
// ------ 阈值 ------
|
|
// 光照阈值,湿度下限阈值,湿度上限阈值,空气质量阈值
|
|
// 光照阈值
|
|
let lightThreshold = deviceAttributesList.find(
|
|
(row) => row.id === 448058556146688
|
|
)?.attributeValue;
|
|
// 湿度下限阈值
|
|
let humidityLowerThreshold = deviceAttributesList.find(
|
|
(row) => row.id === 448058581624832
|
|
)?.attributeValue;
|
|
// 湿度上限阈值
|
|
let humidityUpperThreshold = deviceAttributesList.find(
|
|
(row) => row.id === 448058657266432
|
|
)?.attributeValue;
|
|
// 空气质量阈值
|
|
let airQualityThreshold = deviceAttributesList.find(
|
|
(row) => row.id === 448058718225664
|
|
)?.attributeValue;
|
|
this.deviceInfo = {
|
|
temperature, // 温度
|
|
humidity, // 湿度
|
|
Co2, // Co2
|
|
Tvoc, // Tvoc
|
|
smoke, // 烟雾浓度
|
|
light, // 光照强度
|
|
person, // 是否有人
|
|
alarm, // 声光报警状态
|
|
LED, // LED
|
|
curtain, // 窗帘开关
|
|
humidifier, // 加湿器开关
|
|
fan, // 风扇开关
|
|
airCleaner, // 空气净化器开关
|
|
lightThreshold, // 光照阈值
|
|
humidityLowerThreshold, // 湿度下限阈值
|
|
humidityUpperThreshold, // 湿度上限阈值
|
|
airQualityThreshold, // 空气质量阈值
|
|
};
|
|
console.log("this.deviceInfo", this.deviceInfo);
|
|
// 定时请求接口,每次结束后等待10秒再请求
|
|
this.timer = setTimeout(() => {
|
|
this.getAttributes(this.deviceId); // 根据设备id查找设备信息
|
|
}, 30000);
|
|
}
|
|
},
|
|
},
|
|
created() {
|
|
this.handleLogin();
|
|
},
|
|
onShow() {
|
|
console.log("this.falt", this.falt);
|
|
|
|
if (this.falt) {
|
|
this.getAttributes(this.deviceId); // 根据设备id查找设备信息
|
|
}
|
|
},
|
|
// 离开页面清除定时器
|
|
onHide() {
|
|
console.log("页面即将卸载2");
|
|
clearTimeout(this.timer); // 清除定时器
|
|
},
|
|
};
|
|
</script>
|
|
|
|
<style lang="scss" scoped>
|
|
.threshold {
|
|
margin-top: 16px; // 调整间距
|
|
background: #fff;
|
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
|
border-radius: 10px;
|
|
}
|
|
.view-threshold {
|
|
margin-top: 16px;
|
|
.view-threshold-item {
|
|
margin-bottom: 6px;
|
|
.threshold-item-title {
|
|
font-size: 18px;
|
|
}
|
|
}
|
|
}
|
|
.view-filter {
|
|
filter: grayscale(100%); // 灰度
|
|
}
|
|
.control {
|
|
margin-top: 16px;
|
|
display: flex;
|
|
grid-template-columns: repeat(2, 1fr); // 明确两列布局
|
|
gap: 14px; // 统一间距
|
|
flex-wrap: wrap;
|
|
justify-content: space-between;
|
|
.view-data-item {
|
|
width: 48%;
|
|
display: flex;
|
|
align-items: center;
|
|
box-sizing: border-box;
|
|
padding: 12px;
|
|
background: #fff;
|
|
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
|
|
border-radius: 10px;
|
|
|
|
.data-item-img-box {
|
|
width: 38px;
|
|
height: 38px;
|
|
border-radius: 50%;
|
|
background: rgb(138 213 255 / 10%);
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin-right: 10px;
|
|
.data-item-img {
|
|
width: 22px;
|
|
height: 22px;
|
|
}
|
|
}
|
|
.data-item-text {
|
|
flex: 1;
|
|
color: #999;
|
|
font-size: 18px;
|
|
}
|
|
}
|
|
}
|
|
.view-data {
|
|
padding: 14px;
|
|
margin-top: 45px;
|
|
border-radius: 10px;
|
|
background: linear-gradient(130deg, #cff3ff, #7bacef);
|
|
display: grid;
|
|
grid-template-columns: repeat(2, 1fr); // 明确两列布局
|
|
gap: 6px 14px; // 统一间距
|
|
.view-data-item {
|
|
display: flex;
|
|
align-items: center;
|
|
padding: 8px 0;
|
|
.data-item-img-box {
|
|
width: 38px;
|
|
height: 38px;
|
|
border-radius: 50%;
|
|
background: #fff;
|
|
display: flex;
|
|
justify-content: center;
|
|
align-items: center;
|
|
margin-right: 14px;
|
|
.data-item-img {
|
|
width: 22px;
|
|
height: 22px;
|
|
margin: 10rx;
|
|
}
|
|
}
|
|
.data-item-text {
|
|
color: #3d7ccd;
|
|
font-size: 28px;
|
|
span {
|
|
font-size: 16px;
|
|
font-weight: normal;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
.container {
|
|
padding: 16px;
|
|
box-sizing: border-box;
|
|
min-height: 100vh;
|
|
background: #fcfcfc;
|
|
}
|
|
.title {
|
|
line-height: 40px;
|
|
font-size: 18px;
|
|
text-align: center;
|
|
background: #fff;
|
|
}
|
|
</style>
|
|
<style>
|
|
/deep/ uni-slider {
|
|
margin: 0;
|
|
}
|
|
|
|
/deep/ uni-slider .uni-slider-handle-wrapper {
|
|
height: 10px;
|
|
}
|
|
.navbar /deep/ .u-navbar__content__left {
|
|
display: none !important;
|
|
}
|
|
scroll-view {
|
|
height: 100%;
|
|
position: absolute;
|
|
}
|
|
</style>
|
|
|