跳到主要内容

物模型功能

更新时间:2025-11-26 15:20:44

物模型SDK提供了Web端的物模型(属性、事件、服务),用来开发设备界面,实现Web端对设备的查看和控制。


/**
* 物模型对象接口
* @public
*/
declare interface IThingModelPanel {
/**
* 设备信息
*/
deviceInfo: ISampleDeviceInfo;
/**
* 获取物模型属性
*/
getThingProperties(): Promise<PropertiesMap>;
/**
* 获取物模型模板
*/
getThingTsl(): Promise<ThingTSL>;
/**
* 设置物模型属性
* @param items - 属性
* @param lensId - 镜头ID 可行
*/
setProperties(items: Record<string, any>, lensId?: number): Promise<boolean>;
/**
* 设置属性的超时时间,最小5秒
* @param timeout - 超时时间 单位毫秒
*/
setPropertiesTimeout(timeoutMS: number): void;
/**
* 订阅
* @param callback - 回调
*/
subscribe(callback: IPanelEventCallback): void;
/**
* 取消订阅
* @param callback - 回调
*/
unsubscribe(callback: IPanelEventCallback): void;
/**
* 销毁
*/
destroy(): void;

/**
*
* @param identifier - 服务标识
* @param args - 参数
* @param hasResponse - 是否有返回数据 默认false
* @param lensId - 镜头ID
* @param timeout - 超时时间
*/
invokeService(identifier: string, args?: Record<string, any>, hasResponse?: boolean, lensId?: number, timeout?: number): Promise<InvokeServiceRsp | void>;
}

初始化物对象

建议:应用运行期间,一台设备只需初始化一次物对象。


/**
* 物模型对象
* @public
*/
export declare class RTCXThingModelPanel implements IThingModelPanel {
/**
* @param playDeviceInfo - 设备信息。可从设备列表获取
*/
constructor(playDeviceInfo: RTCXDeviceMgrTypes.PlayDeviceInfo);
}

示例

import {RTCXDeviceMgrTypes, RTCXThingModelTypes, RTCXThingModelPanel} from '@rtcx/websdk'

const currentDeviceInfo = ref<RTCXDeviceMgrTypes.PlayDeviceInfo>()

let thingModelPanel: RTCXThingModelPanel | undefined


enum MyThingPropertyEnum {
powerstate = 'powerstate',
StatusLightSwitch = 'StatusLightSwitch',
}

function getThingModelPanel() {
const deviceInfo = currentDeviceInfo.value
if (!deviceInfo) return console.warn('getThingModelPanel: no device')
if (thingModelPanel && thingModelPanel.deviceInfo.iotId != deviceInfo.iotId) {
thingModelPanel.destroy()
thingModelPanel = undefined
}

if (!thingModelPanel) {
thingModelPanel = new RTCXThingModelPanel(deviceInfo)
thingModelPanel.subscribe(panelEventCallback)
}
return thingModelPanel
}

const panelEventCallback = function (
iotId: string,
eventType: RTCXThingModelTypes.SubscribeEventTypeEnum,
data: unknown
) {
console.info('subscribe panelEventCallback receive ', iotId, eventType, data)
if (eventType == RTCXThingModelTypes.SubscribeEventTypeEnum.DEVICE_THING_PROPERTIES_CHANGE) {
const rsp = data as Record<string, RTCXThingModelTypes.PropertieValue>
const value = rsp[MyThingPropertyEnum.StatusLightSwitch]?.value
if (value !== undefined) {
statusLight.value = value === 1
}
}
}

设备控制

设备控制是基于物的模型对设备定义的属性、事件、服务进行操作。

获取设备属性

多目设备返回的属性的值列表中有多个元素,可根据镜头ID获取列表对应下标元素

/**
* 获取物模型属性
*/
function getThingProperties(): Promise<RTCXThingModelTypes.PropertiesMap>;

示例

import { RTCXThingModelTypes, RTCXThingModelPanel} from '@rtcx/websdk'
const powerState = ref<boolean>()
const statusLight = ref<boolean>()

function initThingModel() {
const thingPanel = getThingModelPanel()
if (!thingPanel) return
thingPanel.getThingProperties().then((propertiesMap: RTCXThingModelTypes.PropertiesMap) => {
console.info('initThingModel propertiesMap', propertiesMap)
const powerstateValue = propertiesMap[MyThingPropertyEnum.powerstate][0]?.value
const statusLightValue = propertiesMap[MyThingPropertyEnum.StatusLightSwitch][0]?.value
powerState.value = Number(powerstateValue) === 1
statusLight.value = Number(statusLightValue) === 1
})
}

设置设备属性

多目设备区分镜头设置属性,可指定镜头设置

/**
* 设置物模型属性
* @param items - 属性
* @param lensId - 镜头ID 可行
*/
function setProperties(items: Record<string, any>, lensId?: number): Promise<boolean>;

示例

import { RTCXThingModelTypes, RTCXThingModelPanel} from '@rtcx/websdk'

const thingModelLoading = ref<boolean>(false)
enum MyThingPropertyEnum {
powerstate = 'powerstate',
StatusLightSwitch = 'StatusLightSwitch',
}

function onStatusLightChange(val: boolean) {
console.info(`onStatusLightChange val=${val}`)
const thingPanel = getThingModelPanel()
if (!thingPanel) return
thingModelLoading.value = true
thingPanel
.setProperties({
[MyThingPropertyEnum.StatusLightSwitch]: val ? 1 : 0,
})
.then(console.info)
.catch(console.error)
.finally(() => {
thingModelLoading.value = false
})
}

注意

当存在录制计划功能时,设置录制计划属性时,各项的时间跨度不可重叠,需要接入应用自行控制

调用设备服务

/**
*
* @param identifier - 服务标识
* @param args - 参数
* @param hasResponse - 是否有返回数据 默认false
* @param lensId - 镜头ID
* @param timeout - 超时时间
*/
function invokeService(identifier: string, args: Record<String, any>, hasResponse?: boolean, lensId?: number, timeout?: number);

//参数格式参考如下
/*
"identifier":"Rhythm",
"args": {
"Saturation":80,
"LightDuration":50,
"Hue":325,
"Value":50
}
*/

调用示例如下:

enum MyThingServiceEnum {
PTZActionControl = 'PTZActionControl',
StartPTZAction = 'StartPTZAction',
StopPTZAction = 'StopPTZAction',
GetPTZPosition = 'GetPTZPosition',
PTZMove = 'PTZMove',
GetWiFiList = 'GetWiFiList',
}
enum PTZSpeedModeEnum {
SLOW,
MIDDLE,
QUICK,
}

enum PTZActionType{
PTZ_LEFT,
PTZ_RIGHT,
PTZ_UP,
PTZ_DOWN,
}
  • PTZ云台控制

PTZ有两种控制方式,一种步进控制设备转动、一种连续控制转动(开始+结束)

import { RTCXThingModelTypes, RTCXThingModelPanel} from '@rtcx/websdk'

const thingPanel = getThingModelPanel()
if (!thingPanel) return
//步进PTZ
const args = {
Step: 10,
ActionType: PTZActionType.PTZ_LEFT,
}
thingPanel.invokeService(MyThingServiceEnum.PTZActionControl, args)

//连续PTZ开始
const args = {
Speed: PTZSpeedModeEnum.MIDDLE,
ActionType: PTZActionType.PTZ_RIGHT,
}
thingPanel.invokeService(MyThingServiceEnum.StartPTZAction, args)
//连续PTZ停止
thingPanel.invokeService(MyThingServiceEnum.StopPTZAction)
  • 获取WiFi列表
import { RTCXThingModelTypes, RTCXThingModelPanel} from '@rtcx/websdk'
function onWiFiGetClick() {
const thingPanel = getThingModelPanel()
if (!thingPanel) return
thingModelLoading.value = true
thingPanel
.invokeService(MyThingServiceEnum.GetWiFiList, undefined, true)
.then(function (rsp: RTCXThingModelTypes.InvokeServiceRsp) {
ElNotification.success('获取WiFi列表成功,请在控制台查看')
console.info('WiFi列表', rsp)
})
.catch(function () {
ElNotification.error('获取PTZ信息失败')
})
.finally(() => {
thingModelLoading.value = false
})
}

获取物的模型

/**
* 获取物模型模板
*/
function getThingTsl(): Promise<ThingTSL>;

示例

import { RTCXThingModelTypes, RTCXThingModelPanel} from '@rtcx/websdk'
function onThingTslGetClick() {
const thingPanel = getThingModelPanel()
if (!thingPanel) return
thingModelLoading.value = true
thingPanel
.getThingTsl()
.then(function (rsp:RTCXThingModelTypes.ThingTSL) {
ElNotification.success('获取物模型模板成功,请在控制台查看')
console.info('物模型模板', rsp)
})
.catch(function () {
ElNotification.error('获取物模型模板失败')
})
.finally(() => {
thingModelLoading.value = false
})
}

订阅设备事件

同一事件可能会多次触发,请在需要时订阅消息,不再需要时及时取消订阅

/**
* 订阅事件类型
* @public
*/
declare enum SubscribeEventTypeEnum {
/**
* 设备解绑
*/
DEVICE_UNBIND = "DEVICE_UNBIND",
/**
* 设备状态
*/
DEVICE_STATUS = "DEVICE_STATUS",
/**
* 设备物模型属性变化
*/
DEVICE_THING_PROPERTIES_CHANGE = "DEVICE_THING_PROPERTIES_CHANGE",
/**
* 设备透传消息
*/
DEV_TRANS_MSG = "DEV_TRANS_MSG"
}

/**
* 订阅事件回调
* @param iotId - 设备ID
* @param eventType - 事件类型
* @param data - 数据
* @public
*/
declare type IPanelEventCallback = (iotId: string, eventType: SubscribeEventTypeEnum, data: unknown) => void;


/**
* 订阅
* @param callback - 回调
*/
function subscribe(callback: RTCXThingModelTypes.IPanelEventCallback): void;
/**
* 取消订阅
* @param callback - 回调
*/
function unsubscribe(callback: RTCXThingModelTypes.IPanelEventCallback): void;

示例

import { RTCXThingModelTypes, RTCXThingModelPanel} from '@rtcx/websdk'

const statusLight = ref<boolean>()
const imageFlipState = ref<boolean>()
/**
*订阅回调
*/
const panelEventCallback = function (
iotId: string,
eventType: RTCXThingModelTypes.SubscribeEventTypeEnum,
data: unknown
) {
console.info('subscribe panelEventCallback receive ', iotId, eventType, data)
if (eventType == RTCXThingModelTypes.SubscribeEventTypeEnum.DEVICE_THING_PROPERTIES_CHANGE) {
const rsp = data as Record<string, RTCXThingModelTypes.PropertieValue>
const statusLightValue = rsp[MyThingPropertyEnum.StatusLightSwitch]?.value
if (statusLightValue !== undefined) {
statusLight.value = statusLightValue === 1
}
const imageFlipStateValue = rsp[MyThingPropertyEnum.ImageFlipState]?.value
if (imageFlipStateValue !== undefined) {
imageFlipState.value = imageFlipStateValue === 1
}
}
}
function getThingModelPanel() {
const deviceInfo = currentDeviceInfo.value
if (!deviceInfo) {
ElNotification.warning('请选择设备')
return
}
if (thingModelPanel && thingModelPanel.deviceInfo.iotId != deviceInfo.iotId) {
thingModelPanel.destroy()
thingModelPanel = undefined
}

if (!thingModelPanel) {
thingModelPanel = new RTCXThingModelPanel(deviceInfo)
//订阅消息
thingModelPanel.subscribe(panelEventCallback)
}
return thingModelPanel
}

取消订阅设备事件

请在不需要订阅消息时及时取消订阅

const thingModelPanel = getThingModelPanel()
thingModelPanel.unsubscribe(panelEventCallback);

销毁

请在不需要物对象时及时销毁

const thingModelPanel = getThingModelPanel()
thingModelPanel.destroy()