feat;simulator

This commit is contained in:
alwayssuper 2025-01-05 22:57:10 +08:00
parent 5e8aad7703
commit b71fa84af3
3 changed files with 135 additions and 50 deletions

View File

@ -63,6 +63,16 @@ export enum DeviceStatusEnum {
DISABLED = 3 // 已禁用 DISABLED = 3 // 已禁用
} }
// IoT 模拟设备数据
export interface SimulatorDataVO {
productKey: string
deviceKey: string
type: string
subType: string
reportTime: string
content: string // 存储 JSON 字符串
}
// 设备 API // 设备 API
export const DeviceApi = { export const DeviceApi = {
// 查询设备分页 // 查询设备分页
@ -136,5 +146,10 @@ export const DeviceApi = {
// 获取导入模板 // 获取导入模板
importDeviceTemplate: async () => { importDeviceTemplate: async () => {
return await request.download({ url: `/iot/device/get-import-template` }) return await request.download({ url: `/iot/device/get-import-template` })
},
// 模拟设备
simulatorDevice: async (data: SimulatorDataVO) => {
return await request.post({ url: `/iot/device/data/simulator`, data })
} }
} }

View File

@ -90,23 +90,23 @@ const typeMap = {
/** 查询日志列表 */ /** 查询日志列表 */
const getLogList = async () => { const getLogList = async () => {
if (!props.deviceId) return // if (!props.deviceId) return
loading.value = true // loading.value = true
try { // try {
const res = await DeviceApi.getDeviceLogs(props.deviceId, queryParams) // const res = await DeviceApi.getDeviceLogs(props.deviceId, queryParams)
total.value = res.total // total.value = res.total
logList.value = res.list.map((item: any) => { // logList.value = res.list.map((item: any) => {
const log = { // const log = {
time: item.time, // time: item.time,
type: typeMap[item.type as keyof typeof typeMap] || item.type, // type: typeMap[item.type as keyof typeof typeMap] || item.type,
name: getLogName(item), // name: getLogName(item),
content: item.content // content: item.content
} // }
return log // return log
}) // })
} finally { // } finally {
loading.value = false // loading.value = false
} // }
} }
/** 获取日志名称 */ /** 获取日志名称 */

View File

@ -11,11 +11,6 @@
<el-tab-pane label="属性上报" name="property"> <el-tab-pane label="属性上报" name="property">
<ContentWrap> <ContentWrap>
<el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true"> <el-table v-loading="loading" :data="list" :show-overflow-tooltip="true" :stripe="true">
<el-table-column label="值" align="center" width="80">
<template #default="scope">
<el-input v-model="scope.row.value" class="!w-60px" />
</template>
</el-table-column>
<el-table-column align="center" label="功能名称" prop="name" /> <el-table-column align="center" label="功能名称" prop="name" />
<el-table-column align="center" label="标识符" prop="identifier" /> <el-table-column align="center" label="标识符" prop="identifier" />
<el-table-column align="center" label="数据类型" prop="identifier"> <el-table-column align="center" label="数据类型" prop="identifier">
@ -87,6 +82,11 @@
</div> </div>
</template> </template>
</el-table-column> </el-table-column>
<el-table-column label="值" align="center" width="80">
<template #default="scope">
<el-input v-model="scope.row.simulateValue" class="!w-60px" />
</template>
</el-table-column>
</el-table> </el-table>
<div class="mt-10px"> <div class="mt-10px">
<el-button type="primary" @click="handlePropertyReport">发送</el-button> <el-button type="primary" @click="handlePropertyReport">发送</el-button>
@ -98,11 +98,6 @@
<el-tab-pane label="事件上报" name="event"> <el-tab-pane label="事件上报" name="event">
<ContentWrap> <ContentWrap>
<el-table v-loading="loading" :data="eventList" :stripe="true"> <el-table v-loading="loading" :data="eventList" :stripe="true">
<el-table-column label="值" align="center" width="80">
<template #default="scope">
<el-input v-model="scope.row.value" class="!w-60px" />
</template>
</el-table-column>
<el-table-column label="功能名称" align="center" prop="name" /> <el-table-column label="功能名称" align="center" prop="name" />
<el-table-column label="标识符" align="center" prop="identifier" /> <el-table-column label="标识符" align="center" prop="identifier" />
<el-table-column label="数据类型" align="center" prop="dataType" /> <el-table-column label="数据类型" align="center" prop="dataType" />
@ -112,6 +107,11 @@
prop="specs" prop="specs"
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
/> />
<el-table-column label="值" align="center" width="80">
<template #default="scope">
<el-input v-model="scope.row.simulateValue" class="!w-60px" />
</template>
</el-table-column>
</el-table> </el-table>
<div class="mt-10px"> <div class="mt-10px">
<el-button type="primary" @click="handleEventReport">发送</el-button> <el-button type="primary" @click="handleEventReport">发送</el-button>
@ -142,11 +142,6 @@
<el-tab-pane label="属性调试" name="propertyDebug"> <el-tab-pane label="属性调试" name="propertyDebug">
<ContentWrap> <ContentWrap>
<el-table v-loading="loading" :data="propertyList" :stripe="true"> <el-table v-loading="loading" :data="propertyList" :stripe="true">
<el-table-column label="值" align="center" width="80">
<template #default="scope">
<el-input v-model="scope.row.value" class="!w-60px" />
</template>
</el-table-column>
<el-table-column label="功能名称" align="center" prop="name" /> <el-table-column label="功能名称" align="center" prop="name" />
<el-table-column label="标识符" align="center" prop="identifier" /> <el-table-column label="标识符" align="center" prop="identifier" />
<el-table-column label="数据类型" align="center" prop="dataType" /> <el-table-column label="数据类型" align="center" prop="dataType" />
@ -156,6 +151,11 @@
prop="specs" prop="specs"
:show-overflow-tooltip="true" :show-overflow-tooltip="true"
/> />
<el-table-column label="值" align="center" width="80">
<template #default="scope">
<el-input v-model="scope.row.simulateValue" class="!w-60px" />
</template>
</el-table-column>
</el-table> </el-table>
<div class="mt-10px"> <div class="mt-10px">
<el-button type="primary" @click="handlePropertyGet">获取</el-button> <el-button type="primary" @click="handlePropertyGet">获取</el-button>
@ -189,7 +189,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { ProductVO } from '@/api/iot/product/product' import { ProductVO } from '@/api/iot/product/product'
import { ThingModelApi, ThingModelData } from '@/api/iot/thingmodel' import { ThingModelApi, ThingModelData } from '@/api/iot/thingmodel'
import { DeviceApi, DeviceVO } from '@/api/iot/device/device' import { DeviceApi, DeviceVO,SimulatorDataVO } from '@/api/iot/device/device'
import DeviceDetailsLog from './DeviceDetailsLog.vue' import DeviceDetailsLog from './DeviceDetailsLog.vue'
import { import {
DataSpecsDataType, DataSpecsDataType,
@ -210,18 +210,22 @@ const queryParams = reactive({
}) })
const dataTypeOptionsLabel = computed(() => (value: string) => getDataTypeOptionsLabel(value)) // const dataTypeOptionsLabel = computed(() => (value: string) => getDataTypeOptionsLabel(value)) //
const props = defineProps<{ product: ProductVO; device: DeviceVO }>() const props = defineProps<{ product: ProductVO; device: DeviceVO }>()
const list = ref<ThingModelData[]>([]) // const list = ref<SimulatorData[]>([]) //
interface SimulatorData extends ThingModelData {
simulateValue?: string | number //
}
/** 查询列表 */ /** 查询列表 */
const getList = async () => { const getList = async () => {
loading.value = true loading.value = true
try { try {
queryParams.productId = props.product?.id || -1 queryParams.productId = props.product?.id || -1
const data = await ThingModelApi.getThingModelList(queryParams) const data = await ThingModelApi.getThingModelList(queryParams)
list.value = data // simulateValue
console.log(data) list.value = data.map(item => ({
console.log(list.value) ...item,
console.log(queryParams) simulateValue: ''
}))
} finally { } finally {
loading.value = false loading.value = false
} }
@ -231,8 +235,6 @@ const getList = async () => {
interface TableItem { interface TableItem {
name: string name: string
identifier: string identifier: string
dataType: string
specs: string
value: string | number value: string | number
} }
@ -243,8 +245,6 @@ const propertyList = computed(() => {
.map((item) => ({ .map((item) => ({
name: item.name, name: item.name,
identifier: item.identifier, identifier: item.identifier,
dataType: item.dataType,
specs: item.specs,
value: '' value: ''
})) }))
}) })
@ -255,8 +255,6 @@ const eventList = computed(() => {
.map((item) => ({ .map((item) => ({
name: item.name, name: item.name,
identifier: item.identifier, identifier: item.identifier,
dataType: item.dataType,
specs: item.specs,
value: '' value: ''
})) }))
}) })
@ -293,22 +291,94 @@ watch(
{ immediate: true } { immediate: true }
) )
interface ReportData {
productKey: string
deviceKey: string
type: string
subType: string
reportTime: string
content: string // string JSON
}
// //
const handlePropertyReport = async () => { const handlePropertyReport = async () => {
// TODO: const contentObj: Record<string, any> = {}
message.success('属性上报成功') list.value.forEach((item) => {
// simulateValue content
if (item.simulateValue !== undefined && item.simulateValue !== '') {
contentObj[item.identifier] = item.simulateValue
}
})
const reportData: SimulatorDataVO = {
productKey: props.product.productKey,
deviceKey: props.device.deviceKey,
type: 'property',
subType: 'report',
reportTime: new Date().toISOString(),
content: JSON.stringify(contentObj) // JSON
}
try {
// TODO: API
console.log('上报数据:', reportData)
console.log('reportData.content', reportData.content)
const data = await DeviceApi.simulatorDevice(reportData)
console.log(data)
message.success('属性上报成功123')
} catch (error) {
message.error('属性上报失败')
}
} }
// //
const handleEventReport = async () => { const handleEventReport = async () => {
// TODO: const contentObj: Record<string, any> = {}
message.success('事件上报成功') list.value
.filter(item => item.type === 'event')
.forEach((item) => {
if (item.simulateValue !== undefined && item.simulateValue !== '') {
contentObj[item.identifier] = item.simulateValue
}
})
const reportData: ReportData = {
productKey: props.product.productKey,
deviceKey: props.device.deviceKey,
type: 'event',
subType: list.value.find(item => item.type === 'event')?.identifier || '',
reportTime: new Date().toISOString(),
content: JSON.stringify(contentObj) // JSON
}
try {
// TODO: API
console.log('上报数据:', reportData)
message.success('事件上报成功')
} catch (error) {
message.error('事件上报失败')
}
} }
// //
const handleDeviceState = async (state: 'online' | 'offline') => { const handleDeviceState = async (state: 'online' | 'offline') => {
// TODO: const reportData: ReportData = {
message.success(`设备${state === 'online' ? '上线' : '下线'}成功`) productKey: props.product.productKey,
deviceKey: props.device.deviceKey,
type: 'status',
subType: state,
reportTime: new Date().toISOString(),
content: JSON.stringify({ status: state }) // JSON
}
try {
// TODO: API
console.log('状态变更数据:', reportData)
console.log('reportData.content111111111', reportData.content)
message.success(`设备${state === 'online' ? '上线' : '下线'}成功`)
} catch (error) {
message.error(`设备${state === 'online' ? '上线' : '下线'}失败`)
}
} }
// //