dp-kit
Info
dp-kit 自 @ray-js/panel-sdk@1.7.0 开始加入
轻量的设备面板 DP 功能点处理工具库,内置支持复杂类型 DP 功能点解析、下发选项 (sendOptions) 增强,以及即时更新等能力。
什么时候需要 dp-kit?
✅ 适合使用:
- 产品有复杂类型 DP 功能点(如 raw/string 类型的
colour_data 需要解析为 hue / saturation / value)
- 需要下发节流、防抖、延迟等控制
- 需要下发后立即更新 UI(
immediate 模式)
- 需要忽略设备上报响应 + 云端 DP 状态同步
- 需要在下发前后注入自定义逻辑(
onBeforeSendDp / onAfterSendDp)
❌ 不需要使用:
- 产品只有简单 DP 功能点类型(
bool / enum / value),直接使用 useProps + useActions 即可
- 不需要任何下发增强能力
接入指南
Step 1: 配置产品 DP 功能点描述文件
src/devices/schema.ts
可参考 创建 SDM
Step 2: 配置复杂 DP 解析文件(可选)
src/devices/protocols.ts
- 这一步对应 createDpKit 的
protocols 字段,用来自定义复杂 DP 功能点的解析与反解析规则(若当前产品不存在复杂 DP 数据,可以跳过)
export const protocols = {
colour_data: {
parser: (dpValue) => ({
hue: parseInt(dpValue.slice(0, 4), 16),
saturation: parseInt(dpValue.slice(4, 8), 16),
value: parseInt(dpValue.slice(8, 12), 16),
}),
formatter: ({ hue, saturation, value }) =>
`${hue.toString(16).padStart(4, '0')}${saturation
.toString(16)
.padStart(4, '0')}${value.toString(16).padStart(4, '0')}`,
},
};
Step 3: 根据业务场景生成 dp-kit
src/devices/index.ts
import { SmartDeviceModel, createDpKit } from '@ray-js/panel-sdk';
import { protocols } from '@/devices/protocols';
import { defaultSchema } from '@/devices/schema';
type SmartDeviceSchema = typeof defaultSchema;
export const dpKit = createDpKit<SmartDeviceSchema>({ protocols });
const options = {
interceptors: dpKit.interceptors,
};
export const devices = {
common: new SmartDeviceModel<SmartDeviceSchema>(options),
};
Step 4: 初始化 dp-kit 复杂 DP 协议数据(可选)
src/app.tsx
- 接入
dpKit.init 初始化复杂 DP 协议数据方法(若不需要复杂数据,可不调用)
Step 5: 全局类型定义接入(可选)
typings/sdm.d.ts
Step 6: 复杂 DP 协议数据获取及下发
src/pages/home/index.tsx
useStructuredProps hooks 接入获取复杂 DP 协议数据
useStructuredActions hooks 接入下发复杂 DP 协议数据
import _ from 'lodash-es';
import React from 'react';
import { View } from '@ray-js/ray';
import { useStructuredProps, useStructuredActions } from '@ray-js/panel-sdk';
export default function Home() {
const colour = useStructuredProps((props) => props.colour_data);
const actions = useStructuredActions();
return (
<View
style={{ flex: 1 }}
onClick={() => {
actions.colour_data.set({
hue: _.random(0, 360),
saturation: _.random(0, 1000),
value: _.random(0, 1000),
});
}}
>
<View>hue: {colour.hue}</View>
<View>saturation: {colour.saturation}</View>
<View>value: {colour.value}</View>
</View>
);
}
API
createDpKit 完整 API 参考和类型定义,请查看 createDpKit API 文档。
以下是 createDpKit 各配置项的使用说明和示例。
复杂 DP 解析配置(可选)
这部分对应 createDpKit 的 protocols 字段,用来指定复杂 DP 功能点的解析方式。配置后会自动解析 & 反解析这类 DP 功能点,无需再在业务代码里进行处理。
const dpKit: Middleware = createDpKit<SmartDeviceSchema>({
protocols: {
colour_data: {
parser: (dpValue) => ({
hue: parseInt(dpValue.slice(0, 4), 16),
saturation: parseInt(dpValue.slice(4, 8), 16),
brightness: parseInt(dpValue.slice(8, 12), 16),
}),
formatter: ({ hue, saturation, brightness }) =>
`${hue.toString(16).padStart(4, '0')}${saturation
.toString(16)
.padStart(4, '0')}${brightness.toString(16).padStart(4, '0')}`,
},
custom_raw_dp: {
parser: (dpValue) => {
// 自定义解析
},
formatter: (dpValue) => {
// 自定义格式化
},
},
},
});
/**
* 获取 colour_data DP 功能点数据
* useProps(props => props.colour_data) = 000003e803e8
* useStructuredProps(props => props.colour_data) = { hue: 0, saturation: 1000, brightness: 1000 }
*/
/**
* 下发 colour_data DP 功能点数据
* const actions = useActions(); => actions.colour_data.set('000003e803e8');
* const actions = useStructuredActions(); => actions.colour_data.set({ hue: 0, saturation: 1000, brightness: 1000 });
*/
如果数据结构比较固定,也可以改用更简短的映射配置;但在教程场景里,优先使用 parser / formatter 通常更直观。
下发选项 (sendOptions)(可选)
下发 DP 功能点的选项,对应 createDpKit 的 sendDpOption 字段。若配置在 createDpKit 中,将影响后续所有的下发指令。
完整类型定义请查看 createDpKit API > SendDpOption
ignoreDpDataResponse 对象配置:
synchronizeDevProperty 对象配置:
例如,如果期望应用内的下发都具有 600ms 的节流,您可以:
const dpKit = createDpKit<SmartDeviceSchema>({
sendDpOption: {
throttle: 600,
},
});
或者,如果期望 DP 功能点不再等到设备上报后才更新,您可以:
const dpKit = createDpKit<SmartDeviceSchema>({
sendDpOption: {
immediate: true,
},
});
注意,通过 dp-kit immediate 即时更新的 DP 功能点数据,在 SDM 内部 onDataChange 事件触发时会额外附带一个 __from__: dp-kit 的回调值,方便业务判断或区分实际 DP 功能点上报自行处理,原始 onDpDataChange 事件则不会被触发。
此外,如果您想针对单个 DP 功能点下发不再等到设备上报后才更新,那么您可以:
const actions = useActions();
actions.power.toggle({ immediate: true });
但仅使用 immediate 在设备上报时还会触发一次更新,容易导致 UI 闪烁。如果期望忽略设备上报的响应,即仅下发,您可以:
const dpKit = createDpKit<SmartDeviceSchema>({
sendDpOption: {
immediate: true,
ignoreDpDataResponse: true, // 忽略设备上报响应
},
});
或者,有部分 DP 功能点需要进行响应,可以使用白名单配置:
const dpKit = createDpKit<SmartDeviceSchema>({
sendDpOption: {
immediate: true,
ignoreDpDataResponse: {
whiteDpCodes: ['switch'], // switch DP 功能点上报时进行响应,其他 DP 功能点上报会忽略
},
},
});
您也可以使用 timeout 参数配置防抖超时时间:
const dpKit = createDpKit<SmartDeviceSchema>({
sendDpOption: {
immediate: true,
ignoreDpDataResponse: {
timeout: 1000 * 5, // 5 秒超时,超过此时间才触发 dpDataChange
},
},
});
或者使用 customRule 自定义忽略规则(优先级最高,配置后 whiteDpCodes 和 timeout 将失效):
const dpKit = createDpKit<SmartDeviceSchema>({
sendDpOption: {
immediate: true,
ignoreDpDataResponse: {
customRule: (dpState, lastSendTimestamp) => {
// 自定义逻辑:仅响应特定 dp 或时间条件
if (dpState.switch !== undefined) {
return true; // switch dp 始终响应
}
if (lastSendTimestamp === null) {
return true; // 首次上报响应
}
const timeDiff = Date.now() - lastSendTimestamp;
return timeDiff > 8000; // 超过 8 秒才响应
},
},
},
});
当忽略设备上报响应时,退出面板重新进入后,设备上一次的状态会无法获取,您可以使用 synchronizeDevProperty 实现拉取云端 DP 状态:
const dpKit = createDpKit<SmartDeviceSchema>({
sendDpOption: {
immediate: true,
ignoreDpDataResponse: {
whiteDpCodes: ['switch'],
},
synchronizeDevProperty: true, // 同步云端设备存储属性
},
});
当每次下发 DP 功能点时,会自动写入到云端设备存储数据。退出面板重新进入时,会做一次 DP 状态初始化,将云端设备存储数据拉取到面板。
同样地,您也可以配置哪些 DP 功能点不需要进行同步:
const dpKit = createDpKit<SmartDeviceSchema>({
sendDpOption: {
synchronizeDevProperty: {
blackDpCodes: ['switch'], // switch DP 功能点不会做云端数据同步
},
},
});
云端数据为空时,可以配置默认值:
const dpKit = createDpKit<SmartDeviceSchema>({
sendDpOption: {
ignoreDpDataResponse: true,
synchronizeDevProperty: {
defaultState: {
switch: false, // switch DP 功能点默认值配置(如果云端数据为空)
},
},
},
});
onBeforeSendDp / onAfterSendDp(可选)
下发 DP 前/后的钩子(在 publishDps 之前/之后),建议传入 SmartDeviceSchema 以确保获得正确的 type。
export const dpKit = createDpKit<SmartDeviceSchema>({
onBeforeSendDp(dpState) {
console.log('=== onBeforeSendDp', dpState);
},
onAfterSendDp(dpState) {
console.log('=== onAfterSendDp', dpState);
},
});
进阶阅读
logger 拦截器
dp-kit 内置了 logger 拦截器,可在控制台查看 DP 下发和上报日志。
logger 文档
matter-kit 拦截器
如果需要同时处理 Matter 设备,可搭配 matter-kit 使用。
matter-kit 文档
SmartDeviceModel 使用指南
dp-kit 基于 SmartDeviceModel 的拦截器机制工作。
SmartDeviceModel 文档
使用 SDM 拦截器和 DP 自定义协议解析
一个基于 dp-kit 的自定义拦截器和自定义协议解析的教程示例。
教程地址
Beacon 设备面板模板
一个基于 dp-kit 内置功能实现的 Beacon 设备面板教程示例。
教程地址