UniApp全栈实战:从零打造智能家居控制平台 | 跨端开发进阶

2025-08-16 0 627

发布日期:2024年4月10日

一、项目架构设计

本教程将开发一个完整的智能家居控制平台,支持以下核心功能:

  • 多端控制:iOS/Android/小程序/H5统一体验
  • 设备配网:蓝牙/WiFi双模智能连接
  • 场景联动:可视化规则引擎
  • 实时监控:WebSocket数据推送
  • 语音控制:集成主流语音助手

技术栈:UniApp + Vue3 + uView UI + MQTT + ECharts

二、项目初始化与配置

1. 创建UniApp项目

# 使用Vue3/Vite模板
npx degit dcloudio/uni-preset-vue#vite smart-home

# 安装依赖
cd smart-home
npm install
npm install uview-ui mqtt.js echarts wx-ble

2. 多端适配配置

// manifest.json 配置
{
  "app-plus": {
    "usingComponents": true,
    "nvueCompiler": "uni-app"
  },
  "mp-weixin": {
    "appid": "YOUR_WX_APPID",
    "requiredBackgroundModes": ["bluetooth"]
  },
  "h5": {
    "router": {
      "mode": "history"
    }
  }
}

// 条件编译处理
// #ifdef APP-PLUS
const deviceModule = uni.requireNativePlugin('DeviceModule')
// #endif
// #ifdef MP-WEIXIN
const ble = require('./utils/wx-ble.js')
// #endif

三、设备连接核心实现

1. 蓝牙设备发现与连接

// utils/ble-connector.js
export class BleConnector {
  static async searchDevices() {
    // #ifdef APP-PLUS
    const devices = await uni.startBluetoothDevicesDiscovery({
      services: ['0000FFE0-0000-1000-8000-00805F9B34FB']
    })
    // #endif
    
    // #ifdef MP-WEIXIN
    const devices = await ble.startDiscovery()
    // #endif
    
    return devices.map(device => ({
      name: device.name,
      deviceId: device.deviceId,
      RSSI: device.RSSI
    }))
  }

  static async connect(deviceId) {
    // #ifdef APP-PLUS
    const connection = await uni.createBLEConnection({ deviceId })
    // #endif
    
    // #ifdef MP-WEIXIN
    const connection = await ble.connectDevice(deviceId)
    // #endif
    
    return {
      ...connection,
      onDisconnect: (callback) => {
        uni.onBLEConnectionStateChange(state => {
          if (!state.connected) callback()
        })
      }
    }
  }
}

2. WiFi设备配网模块

// utils/wifi-config.js
export async function smartConfig(wifiInfo) {
  // 通用UDP广播配网
  const udp = uni.createUDPSocket()
  const configData = this.generateConfigPacket(wifiInfo)
  
  udp.send({
    address: '255.255.255.255',
    port: 10000,
    message: configData
  })
  
  return new Promise((resolve) => {
    udp.onMessage(res => {
      if (res.message.toString() === 'ACK') {
        resolve(true)
      }
    })
    
    setTimeout(() => resolve(false), 10000)
  })
}

function generateConfigPacket({ ssid, password }) {
  // 生成设备特定的配网数据包
  const encoder = new TextEncoder()
  return encoder.encode(
    `WIFI:${ssid}:${password}:${Date.now()}`
  )
}

四、实时通信系统

1. MQTT服务封装

// services/mqtt.js
import mqtt from 'mqtt/dist/mqtt.min'

export class MQTTClient {
  constructor() {
    this.client = null
    this.subscriptions = new Map()
  }

  connect(options) {
    return new Promise((resolve, reject) => {
      this.client = mqtt.connect('wxs://iot.example.com/mqtt', {
        clientId: `client_${Date.now()}`,
        ...options
      })

      this.client.on('connect', () => {
        this.resubscribe()
        resolve()
      })

      this.client.on('message', (topic, payload) => {
        const handlers = this.subscriptions.get(topic) || []
        handlers.forEach(handler => 
          handler(JSON.parse(payload.toString()))
        )
      })

      this.client.on('error', reject)
    })
  }

  subscribe(topic, callback) {
    if (!this.subscriptions.has(topic)) {
      this.subscriptions.set(topic, [])
      this.client.subscribe(topic)
    }
    this.subscriptions.get(topic).push(callback)
  }

  publish(topic, message) {
    this.client.publish(topic, JSON.stringify(message))
  }
}

2. 消息协议设计

// protocals/device-message.js
export const MessageType = {
  STATUS_UPDATE: 1,
  CONTROL_COMMAND: 2,
  ALERT_NOTIFICATION: 3
}

export function encodeMessage(type, payload) {
  return {
    ver: 1,
    timestamp: Date.now(),
    type,
    payload,
    checksum: this.calculateChecksum(payload)
  }
}

export function decodeMessage(raw) {
  if (raw.ver !== 1) throw new Error('协议版本不匹配')
  if (raw.checksum !== this.calculateChecksum(raw.payload)) {
    throw new Error('校验失败')
  }
  
  return {
    type: raw.type,
    data: raw.payload,
    timestamp: raw.timestamp
  }
}

五、控制界面开发

1. 设备控制卡片组件

<template>
  <view class="device-card" :class="[statusClass, { disabled: !device.online }]">
    <view class="header" @click="toggleExpand">
      <u-icon :name="device.icon" size="24"></u-icon>
      <text class="name">{{ device.name }}</text>
      <u-badge :value="device.alerts" v-if="device.alerts"></u-badge>
    </view>
    
    <view class="controls" v-if="expanded">
      <template v-for="control in device.controls">
        <switch-control 
          v-if="control.type === 'switch'" 
          :model-value="control.value"
          @change="handleControl(control.key, $event)"
        />
        <slider-control
          v-else-if="control.type === 'slider'"
          :model-value="control.value"
          @change="handleControl(control.key, $event)"
        />
      </template>
    </view>
  </view>
</template>

<script setup>
const props = defineProps({
  device: {
    type: Object,
    required: true
  }
})

const emit = defineEmits(['control'])

const expanded = ref(false)

const statusClass = computed(() => {
  return props.device.status === 'active' ? 'active' : 'inactive'
})

function handleControl(key, value) {
  emit('control', {
    deviceId: props.device.id,
    key,
    value
  })
}
</script>

2. 场景联动编辑器

<template>
  <view class="scene-editor">
    <view class="condition" v-for="(cond, index) in conditions" :key="index">
      <picker 
        :value="cond.deviceId" 
        @change="selectDevice(index, $event)"
        range="devices"
        range-key="name"
      >
        <view>{{ getDeviceName(cond.deviceId) || '选择设备' }}</view>
      </picker>
      
      <!-- 条件与动作配置UI -->
    </view>
    
    <u-button @click="addCondition">添加条件</u-button>
    <u-button @click="saveScene" type="primary">保存场景</u-button>
  </view>
</template>

<script setup>
const devices = ref([])
const conditions = ref([{ deviceId: '', trigger: '', actions: [] }])

onMounted(async () => {
  devices.value = await fetchDevices()
})

function addCondition() {
  conditions.value.push({ deviceId: '', trigger: '', actions: [] })
}

async function saveScene() {
  await api.createScene({
    name: '自定义场景',
    conditions: conditions.value
  })
  uni.showToast({ title: '保存成功' })
}
</script>

六、多端适配方案

1. 平台特定代码处理

// utils/voice-control.js
export function initVoiceControl() {
  // #ifdef APP-PLUS
  const voice = uni.requireNativePlugin('VoiceControl')
  voice.init({
    appId: 'YOUR_APP_ID'
  })
  return voice
  // #endif
  
  // #ifdef MP-WEIXIN
  return wx.startVoiceRecognize({
    lang: 'zh_CN'
  })
  // #endif
  
  // #ifdef H5
  return new Promise((resolve) => {
    if ('webkitSpeechRecognition' in window) {
      resolve(new window.webkitSpeechRecognition())
    } else {
      uni.showModal({
        title: '提示',
        content: '当前浏览器不支持语音识别'
      })
    }
  })
  // #endif
}

2. 响应式布局设计

// composables/useResponsive.js
import { ref, onMounted, onUnmounted } from 'vue'

export function useResponsive() {
  const screenWidth = ref(uni.getSystemInfoSync().windowWidth)
  const isMobile = computed(() => screenWidth.value  screenWidth.value >= 768 && screenWidth.value  screenWidth.value >= 992)

  const updateSize = () => {
    screenWidth.value = uni.getSystemInfoSync().windowWidth
  }

  onMounted(() => {
    uni.onWindowResize(updateSize)
  })

  onUnmounted(() => {
    uni.offWindowResize(updateSize)
  })

  return { isMobile, isTablet, isDesktop }
}

七、打包发布与优化

1. 多平台构建命令

# 微信小程序
npm run build:mp-weixin

# H5
npm run build:h5

# App打包
npm run build:app-plus
# 生成Android APK
cd dist/build/app-plus && zip -r ../android.zip ./*

# iOS打包(需Xcode)
open /dist/build/app-plus/ios

2. 性能优化策略

// 图片懒加载
<image 
  lazy-load 
  :src="imageUrl" 
  mode="aspectFill"
></image>

// 组件按需加载
const HeavyComponent = defineAsyncComponent(() =>
  import('./HeavyComponent.vue')
)

// 数据缓存
uni.setStorage({
  key: 'device_list',
  data: JSON.stringify(devices.value),
  success: () => {
    console.log('缓存成功')
  }
})

八、总结与扩展

通过本教程,您已经掌握了:

  1. UniApp物联网应用开发全流程
  2. 多端设备连接与控制
  3. 实时通信系统的实现
  4. 复杂交互界面的开发
  5. 跨平台适配方案

扩展学习方向:

  • 机器学习设备行为预测
  • WebAssembly性能优化
  • 3D设备可视化
  • 离线语音控制集成
UniApp全栈实战:从零打造智能家居控制平台 | 跨端开发进阶
收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

淘吗网 uniapp UniApp全栈实战:从零打造智能家居控制平台 | 跨端开发进阶 https://www.taomawang.com/web/uniapp/855.html

常见问题

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务