---
name: "useStructuredActions"
mode: "api"
versionRequirements:
  - { name: "@ray-js/panel-sdk", version: "1.10.0" }
title: "useStructuredActions - 基于 sdm 实例及 dp-kit 拦截器实现"
summary: "useStructuredActions 是 @ray-js/panel-sdk 提供的 React Hook，基于 sdm 实例及 dp-kit 拦截器实现，能根据 protocols 协议文件自动将结构化数据转为设备可识别的 DP 指令并下发（如 actions.colour_data.set({ hue, saturation, value })），只返回配置了协议规则的功能点下发方法，支持单设备和群组，常与 useStructuredProps 搭配使用。"
questions:
  - "如何下发raw类型的dp点？如何下发结构化复杂类型的dp点？"
  - "useStructuredActions 如何根据 protocols 协议文件自动转化结构化复杂类型功能点数据并下发？"
  - "actions.colour_data.set({ hue, saturation, value }) 是如何将结构化数据转为设备可识别的 DP 指令的？"
  - "useStructuredActions 只返回配置了协议规则的功能点下发方法，不返回基础类型，这是为什么？"
  - "使用 useStructuredActions 前需要先配置接入 dp-kit 拦截器，具体在哪里配置？"
  - "useStructuredActions 与 useActions 的区别是什么（结构化复杂类型下发 vs 基础功能点下发）？"
  - "useStructuredActions 无参数，返回值 actions 的类型 GetStructuredActions 是如何根据协议推导的？"
  - "如何将 useStructuredProps 与 useStructuredActions 搭配使用实现彩光功能点的读取和下发？"
  - "useStructuredActions 同时支持单设备和群组设备，下发指令时群组会发送到所有子设备吗？"
  - "useStructuredActions 的更多信息参考 dp-kit 拦截器文档，dp-kit 提供了哪些功能点处理能力？"
  - "使用 useStructuredActions 下发 colour_data 时 hue 范围是 0-360、saturation 和 value 范围是 0-1000 吗？"
---

<div style={{ display: 'flex', gap: '8px', marginBottom: '16px' }}>
  <span style={{ backgroundColor: '#52c41a', color: 'white', padding: '2px 8px', borderRadius: '4px', fontSize: '12px' }}>单设备支持</span>
  <span style={{ backgroundColor: '#52c41a', color: 'white', padding: '2px 8px', borderRadius: '4px', fontSize: '12px' }}>群组支持</span>
</div>

## useStructuredActions

> [VERSION] @ray-js/panel-sdk >= 1.10.0

> 💡 基于 sdm 实例及 dp-kit 拦截器实现。必须在 SdmProvider 内部使用。
> 使用前请注意检查项目是否已挂载了 SdmProvider，项目接入可参考 [智能设备模型 - 使用](/cn/miniapp/solution-panel/ability/common/sdm/usage)，全新项目可直接基于 [public-sdm](https://github.com/Tuya-Community/tuya-ray-materials/tree/main/template/PublicSdmTemplate) 示例项目进行开发。
> 使用前请注意检查是否已配置接入了 dp-kit 拦截器，项目接入可参考 [拦截器 - 使用](/cn/miniapp/solution-panel/ability/common/sdm/interceptors/usage)。
> 只返回配置了协议规则的功能点下发方法，不包含基础类型功能点（基础类型请用 useActions）。
> 同时支持单设备（SmartDeviceModel）和群组设备（SmartGroupModel）。与 useStructuredProps 对称使用：useStructuredProps 通过 Transformer.parser() 读取结构化数据，
> useStructuredActions 通过 Transformer.formatter() 将结构化数据转为 DP 指令下发。

### 描述

获取经 dp-kit 协议转化后的结构化功能点下发方法集合

### 参数

无


### 返回值

类型: `Record<DpCode, { set: (value: object, options?: SendDpOption) => Promise<boolean> }>`

结构化功能点下发方法集合，key 为配置了 protocols 的 DP code，每个 key 提供 set(structuredValue) 方法；set 的入参类型由对应 Transformer.formatter() 的参数类型决定，内部自动调用 formatter 将结构化数据转为 DP 字符串后下发设备

### 引用对象

##### `type` SendDpOption

DP 下发选项，可作为 createDpKit 的全局默认配置，也可在单次 publishDps / action 调用时覆盖。
全局 `sendDpOption` 适合声明产品级默认行为；
单次下发传入的 options 适合临时覆盖节流、防抖、协议解析或乐观更新策略。
注：依赖 dp-kit 拦截器才可使用。

| 属性 | 类型 | 最低版本 | 描述 |
| --- | --- | --- | --- |
| `immediate` | `boolean` | - | 是否立即触发 state 更新，必须依赖 dp-kit 拦截器才可使用 |
| `ignoreDpDataResponse` | `boolean \| IgnoreDpChangeInterceptorOptions` | `1.11.0` | 是否忽略 DP 功能点上报，默认 false |
| `synchronizeDevProperty` | `boolean \| DevPropInterceptorOptions` | `1.11.0` | 是否将 dpData 和云端设备属性同步，默认 false |
| `ordered` | `boolean` | - | 多个 DP 是否按对象里的顺序下发，必须依赖 dp-kit 拦截器才可使用，默认 false |
| `checkRepeat` | `boolean` | - | 是否进行重复值判断不下发，必须依赖 dp-kit 拦截器才可使用，默认 false 与当前 `dpState` 进行比较，重复值检出不下发 |
| `delay` | `number` | - | 延迟下发，必须依赖 dp-kit 拦截器才可使用，默认 0，单位 ms |
| `throttle` | `number` | - | 下发节流 (与防抖冲突)，必须依赖 dp-kit 拦截器才可使用，默认 0，单位 ms |
| `debounce` | `number` | - | 下发防抖 (与节流冲突)，必须依赖 dp-kit 拦截器才可使用，默认 0，单位 ms |
| `protocols` | `Record<string, CustomRawDpMap>` | - | 单次下发时临时指定的 DP 协议转换器，必须依赖 dp-kit 拦截器才可使用。 key 为 dpCode，value 为 `{ parser, formatter }` 对象： - parser(dpValue: string) => any — 将原始 DP 字符串解析为结构化对象 - formatter(parsedValue: any) => string — 将结构化对象序列化为 DP 字符串 仅影响本次调用，不覆盖 createDpKit 中的全局 protocols 配置 |

##### `type` IgnoreDpChangeInterceptorOptions

忽略 DP 数据变化拦截器的配置选项

用于配置智能设备面板中 DP 上报事件的防抖机制，避免面板操作后的
即时响应干扰用户体验或业务逻辑

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `whiteDpCodes` | `string[]` | 白名单 dp，不会忽略上报 |
| `timeout` | `number` | 防抖超时检查，毫秒，默认为 5000 - 从面板下发 dp 到收到 dp 回复之间的最大时间，超过此时间才会触发 dpDataChange。 - 用于 dp 上报事件的防抖 |
| `customRule` | `(dpState: DpState, lastSendTimestamp: number) => boolean` | 自定义忽略规则 > 优先级最高，配置了自定义规则后，whiteDpCodes 和 timeout 项将无效 |

##### `type` DevPropInterceptorOptions

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `blackDpCodes` | `string[]` | 黑名单 dp，不会同步到云端 |
| `defaultState` | `DpState` | 首次进入时，默认的设备状态, 支持异步初始化 |
| `throttle` | `number` | 下发节流，毫秒，默认为 0 如果设置为 0，则不进行节流。 |

##### `type` DpState

功能点状态对象，key 为功能点 code，value 为功能点值

```typescript
export type DpState = Record<string, DpValue>;
```

##### `type` CustomRawDpMap

自定义 DP 协议转换器，用于将原始 DP 字符串与结构化对象互转。
适用于 raw/string 类型的复合 DP（如灯的 colour_data "00ff003e8"），
将单个字符串拆解为多个语义字段（如 { hue, saturation, value }）。

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `parser` | `(dpValue: string) => any` | 将设备上报的原始 DP 字符串解析为结构化对象 |
| `formatter` | `(parsedDpValue: any) => string` | 将结构化对象序列化为下发给设备的 DP 字符串 |

##### `interface` DpSchema

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `attr` | `number` | 功能点属性标位，用于扩展功能点的附加能力标识 |
| `canTrigger` | `boolean` | 是否可作为自动化触发条件 |
| `code` | `string` | 功能点标识码，如 switch |
| `defaultRecommend` | `boolean` | 是否为默认推荐的功能点 |
| `editPermission` | `boolean` | 是否具有编辑权限 |
| `executable` | `boolean` | 是否可执行下发 |
| `extContent` | `string` | 功能点扩展内容，通常为 JSON 字符串 |
| `iconname` | `string` | 功能点图标名称 |
| `id` | `string \| number` | 功能点 ID |
| `mode` | `"rw" \| "ro" \| "wr"` | 功能点模式类型 rw: 可下发可上报（可读可写） ro: 只可上报（仅可读） wr: 只可下发（仅可写） |
| `name` | `string` | 功能点名称，一般用于语音等场景 |
| `property` | `Object` | 功能点属性 |
| `type` | `"raw" \| "obj"` | 功能点数据类型大类：raw 为原始字节流，obj 为结构化对象 |

##### `type` DpValue

功能点值类型，可能为 boolean、number、string

```typescript
export type DpValue = boolean | number | string;
```

##### `type` DpSchema.property

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `type` | `"string" \| "bool" \| "value" \| "enum" \| "bitmap" \| "raw"` | 功能点类型 |
| `range` | `string[] \| string[]` | 枚举值范围，type = enum 时才存在 |
| `label` | `string[] \| string[]` | 故障型标签列表，type = bitmap 时才存在 |
| `maxlen` | `number` | 故障型最大长度，type = bitmap 时才存在 |
| `unit` | `string` | 数值型单位，type = value 时才存在 |
| `min` | `number` | 数值型最小值，type = value 时才存在 |
| `max` | `number` | 数值型最大值，type = value 时才存在 |
| `scale` | `number` | 数值型精度，type = value 时才存在 |
| `step` | `number` | 数值型步长，type = value 时才存在 |


### 示例代码

#### 完整链路：读取 + 下发（以照明 colour_data 为例）

```tsx
// ---- 1. devices/protocols/index.ts：实例化 parser 并映射到 DP code ----
import { protocols as sdkProtocols } from '@ray-js/panel-sdk';
import { lampSchemaMap } from '../schema';

export const protocols = {
  [lampSchemaMap.colour_data.code]: new sdkProtocols.ColourTransformer(),
  // ColourTransformer.parser()  返回 { hue, saturation, value } → useStructuredProps 读
  // ColourTransformer.formatter() 接收 { hue, saturation, value } → useStructuredActions 写
};

// ---- 2. devices/index.ts：创建 dpKit 并传给 sdm 实例 ----
import { SmartDeviceModel, createDpKit } from '@ray-js/panel-sdk';
import { protocols } from '@/devices/protocols';

export const dpKit = createDpKit({ protocols });
export const devices = {
  lamp: new SmartDeviceModel({ interceptors: dpKit.interceptors }),
};

// ---- 3. 页面组件：通过 useStructuredActions 下发结构化数据 ----
import { View, Text } from '@ray-js/ray';
import { useStructuredProps, useStructuredActions } from '@ray-js/panel-sdk';

export default function Home() {
  // 读：parser() 返回值决定 colour 的类型 { hue, saturation, value }
  const colour = useStructuredProps(props => props.colour_data);
  // 写：set() 入参类型 = formatter() 的参数类型，同为 { hue, saturation, value }
  const actions = useStructuredActions();

  return (
    <View onClick={() => actions.colour_data.set({ hue: 120, saturation: 800, value: 900 })}>
      <Text>hue: {colour.hue}</Text>
      <Text>saturation: {colour.saturation}</Text>
      <Text>value: {colour.value}</Text>
    </View>
  );
}
```
