快速开始
概述
本指南将帮助您快速集成店滴物联网云平台的 uni-app JavaScript SDK,实现设备数据展示和远程控制功能。
环境要求
- uni-app 项目
- Vue 3
- Pinia(状态管理)
- 支持 WebSocket 的运行环境
第一步:安装 SDK
将 SDK 文件复制到您的 uni-app 项目中:
uni_modules/ddiot-ui/js_sdk/
├── index.js # 主 SDK 入口
├── websocket/ # WebSocket 相关
│ └── ddiot_websocket.js
├── http/ # HTTP 请求相关
├── libs/ # 工具库
└── api/ # API 接口
第二步:配置项目
1. 修改 main.js
import App from './App'
import ddiot from '@/uni_modules/ddiot-ui/js_sdk/index.js'
import diandi from './config.js'
import { createPinia } from 'pinia'
// #ifdef VUE3
import { createSSRApp } from 'vue'
export function createApp() {
const app = createSSRApp(App)
const pinia = createPinia()
app.use(pinia)
// 全局挂载
app.config.globalProperties.$ddiot = ddiot
// 初始化 ddiot 插件
app.use(ddiot, {
websocketConf: {
url: "wss://your-server.com/addons",
authUrl: 'wss://your-server.com/auth',
heartRateType: 'heart',
heartRate: 20000,
app_id: 'your_app_id',
app_secret: 'your_app_secret',
},
http: {
successCode: 200,
apiConfig: {
baseUrl: 'https://your-api.com',
// 其他配置...
}
}
})
return { app }
}
// #endif
2. 创建配置文件 config.js
export default {
wxapp_id: 'your_wxapp_id',
bloc_id: 1,
store_id: 1,
baseUrl: 'https://your-api.com',
siteUrl: 'https://your-site.com',
iotUrl: 'https://your-iot-api.com'
}
第三步:创建设备数据展示页面
1. 创建页面文件
创建 pages/device/device.vue:
<template>
<view class="container">
<!-- 设备状态卡片 -->
<view class="device-card" v-if="deviceData">
<view class="device-header">
<text class="device-name">{{ deviceData.name }}</text>
<text class="device-status" :class="{ online: deviceData.online }">
{{ deviceData.online ? '在线' : '离线' }}
</text>
</view>
<!-- 数据展示 -->
<view class="data-grid">
<view class="data-item" v-for="item in deviceData.properties" :key="item.id">
<text class="data-label">{{ item.label }}</text>
<text class="data-value">{{ item.value }}{{ item.unit }}</text>
</view>
</view>
<!-- 控制按钮 -->
<view class="control-buttons">
<button class="btn" @click="refreshData">刷新数据</button>
<button class="btn primary" @click="showControlPanel">控制面板</button>
</view>
</view>
<!-- 加载状态 -->
<view class="loading" v-if="loading">
<text>加载中...</text>
</view>
</view>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const $ddiot = proxy.$ddiot
// 数据状态
const deviceData = ref(null)
const loading = ref(false)
const websocket = ref(null)
// 获取设备数据
const fetchDeviceData = async (deviceMac) => {
loading.value = true
try {
const response = await $ddiot.request('/device/deviceGroup', 'POST', {
device_mac: deviceMac
}, true, { scene: 'iot' })
if (response.code === 200) {
deviceData.value = formatDeviceData(response.data)
}
} catch (error) {
console.error('获取设备数据失败:', error)
$ddiot.toast('获取设备数据失败')
} finally {
loading.value = false
}
}
// 格式化设备数据
const formatDeviceData = (data) => {
// 这里根据你的数据结构进行格式化
return {
name: data.title || '未知设备',
online: data.online || false,
properties: data.child_device?.[0]?.property || []
}
}
// 刷新数据
const refreshData = () => {
fetchDeviceData('your_device_mac')
}
// 显示控制面板
const showControlPanel = () => {
uni.navigateTo({
url: '/pages/device/control?mac=your_device_mac'
})
}
// 初始化 WebSocket
const initWebSocket = async () => {
try {
const ws = await $ddiot.createSocket('addons')
websocket.value = ws
// 监听设备数据更新
ws.on('device_data_update', (message) => {
console.log('设备数据更新:', message)
// 更新本地数据
if (message.data) {
deviceData.value = formatDeviceData(message.data)
}
})
// 监听连接状态
ws.on('connectioned', () => {
console.log('WebSocket 连接成功')
})
ws.on('error', (error) => {
console.error('WebSocket 错误:', error)
})
} catch (error) {
console.error('WebSocket 初始化失败:', error)
}
}
// 生命周期
onMounted(() => {
fetchDeviceData('your_device_mac')
initWebSocket()
})
</script>
<style scoped>
.container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
.device-card {
background: white;
border-radius: 16rpx;
padding: 30rpx;
margin-bottom: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.1);
}
.device-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 30rpx;
}
.device-name {
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.device-status {
font-size: 28rpx;
color: #999;
}
.device-status.online {
color: #4CAF50;
}
.data-grid {
display: grid;
grid-template-columns: repeat(2, 1fr);
gap: 20rpx;
margin-bottom: 30rpx;
}
.data-item {
background: #f8f8f8;
padding: 20rpx;
border-radius: 8rpx;
text-align: center;
}
.data-label {
display: block;
font-size: 24rpx;
color: #666;
margin-bottom: 10rpx;
}
.data-value {
display: block;
font-size: 32rpx;
font-weight: bold;
color: #333;
}
.control-buttons {
display: flex;
gap: 20rpx;
}
.btn {
flex: 1;
padding: 20rpx;
border: none;
border-radius: 8rpx;
font-size: 28rpx;
background: #f0f0f0;
color: #333;
}
.btn.primary {
background: #007AFF;
color: white;
}
.loading {
text-align: center;
padding: 40rpx;
color: #999;
}
</style>
第四步:创建设备控制页面
1. 创建控制页面
创建 pages/device/control.vue:
<template>
<view class="container">
<view class="control-panel" v-if="deviceFunctions.length > 0">
<view class="function-group" v-for="group in deviceFunctions" :key="group.id">
<view class="group-title">{{ group.title }}</view>
<view class="function-grid">
<view
class="function-item"
v-for="func in group.function"
:key="func.id"
@click="executeFunction(func)"
>
<view class="function-label">{{ func.label }}</view>
<view class="function-value">{{ func.value }}{{ func.unit }}</view>
</view>
</view>
</view>
</view>
<view class="loading" v-if="loading">
<text>加载控制功能...</text>
</view>
</view>
</template>
<script setup>
import { ref, onMounted, getCurrentInstance } from 'vue'
const { proxy } = getCurrentInstance()
const $ddiot = proxy.$ddiot
// 数据状态
const deviceFunctions = ref([])
const loading = ref(false)
const websocket = ref(null)
// 获取设备功能
const fetchDeviceFunctions = async (deviceMac) => {
loading.value = true
try {
const response = await $ddiot.request('/device/deviceGroup', 'POST', {
device_mac: deviceMac
}, true, { scene: 'iot' })
if (response.code === 200) {
deviceFunctions.value = response.data.child_device || []
}
} catch (error) {
console.error('获取设备功能失败:', error)
$ddiot.toast('获取设备功能失败')
} finally {
loading.value = false
}
}
// 执行设备功能
const executeFunction = (func) => {
if (!websocket.value || !websocket.value._connectioned) {
$ddiot.toast('WebSocket 连接未就绪')
return
}
try {
websocket.value.emit("operation", {
"device_id": Number(func.device_id),
"id": func.instruction_id,
"imei": func.device_mac,
}, 'yrddtu', 'dtu', 'command')
$ddiot.toast('指令已发送', 1500, true)
} catch (error) {
console.error('发送指令失败:', error)
$ddiot.toast('发送指令失败')
}
}
// 初始化 WebSocket
const initWebSocket = async () => {
try {
const ws = await $ddiot.createSocket('addons')
websocket.value = ws
// 监听命令响应
ws.on('command_res', (message) => {
console.log('命令响应:', message)
if (message.code === 200) {
$ddiot.toast('操作成功', 1500, true)
} else {
$ddiot.toast('操作失败: ' + message.message)
}
})
// 监听操作成功
ws.on('operation_success', (message) => {
console.log('操作成功:', message)
$ddiot.toast('操作成功', 1500, true)
})
// 监听操作错误
ws.on('operation_error', (message) => {
console.log('操作错误:', message)
$ddiot.toast('操作错误: ' + message.message)
})
} catch (error) {
console.error('WebSocket 初始化失败:', error)
}
}
// 生命周期
onMounted(() => {
const deviceMac = getCurrentPages()[getCurrentPages().length - 1].$page.options.mac
if (deviceMac) {
fetchDeviceFunctions(deviceMac)
initWebSocket()
} else {
$ddiot.toast('缺少设备标识')
uni.navigateBack()
}
})
</script>
<style scoped>
.container {
padding: 20rpx;
background-color: #f5f5f5;
min-height: 100vh;
}
.control-panel {
background: white;
border-radius: 16rpx;
padding: 20rpx;
box-shadow: 0 4rpx 16rpx rgba(0,0,0,0.1);
}
.function-group {
margin-bottom: 30rpx;
}
.group-title {
font-size: 32rpx;
font-weight: bold;
color: #333;
margin-bottom: 20rpx;
padding: 20rpx 0;
border-bottom: 1rpx solid #eee;
}
.function-grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20rpx;
}
.function-item {
background: #f8f8f8;
padding: 30rpx 20rpx;
border-radius: 12rpx;
text-align: center;
transition: all 0.3s ease;
}
.function-item:active {
background: #e0e0e0;
transform: scale(0.95);
}
.function-label {
font-size: 28rpx;
color: #333;
margin-bottom: 10rpx;
}
.function-value {
font-size: 24rpx;
color: #666;
}
.loading {
text-align: center;
padding: 40rpx;
color: #999;
}
</style>
第五步:配置页面路由
在 pages.json 中添加页面配置:
{
"pages": [
{
"path": "pages/device/device",
"style": {
"navigationBarTitleText": "设备数据"
}
},
{
"path": "pages/device/control",
"style": {
"navigationBarTitleText": "设备控制"
}
}
]
}
第六步:测试运行
- 编译并运行项目
- 访问设备数据页面,查看设备状态和数据
- 点击控制面板按钮,进入设备控制页面
- 尝试点击功能按钮,发送控制指令
常见问题
Q: WebSocket 连接失败怎么办?
A: 检查服务器地址是否正确,网络是否正常,认证信息是否有效。
Q: 设备数据不更新?
A: 确认 WebSocket 连接状态,检查设备是否在线,查看控制台是否有错误信息。
Q: 控制指令发送失败?
A: 检查 WebSocket 连接状态,确认设备功能参数是否正确,查看服务器响应。
下一步
- 学习 WebSocket 详细文档
- 了解 主 SDK 接口文档
- 查看 完整 API 文档
