---
name: "useDevicesActions"
mode: "api"
versionRequirements:
  - { name: "@ray-js/panel-sdk", version: "1.16.0" }
title: "useDevicesActions"
summary: "多设备管理 useDevicesActions Hook 说明，介绍如何获取多台设备的 DP 下发操作方法，执行 set、on、off、toggle 等控制。"
---

## useDevicesActions

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

> 💡 注意事项：
> 使用前需挂载 SdmDevicesProvider 并配置关联设备映射。
> 常与 useDevicesProps 搭配使用，useDevicesProps 读取状态、useDevicesActions 下发指令。
> 该 Hooks 返回的 actions 方法是对底层 publishDps 的封装，调用 actions 并不会导致组件立即重渲染。
> 只有当指令下发成功且设备上报新的 DP 状态时，使用了对应 useDevicesProps 且 selector 命中的组件才会被触发重渲染。

### 描述

获取关联设备的功能点操作方法集合

### 参数

无


### 返回值

类型: `{ [key: string]: DpActions }`

设备操作方法集合，key 为设备标识，value 为该设备的 actions 对象。
  每个设备的 actions 使用方式与单设备 useActions 一致

### 引用对象

##### `interface` DpActions

| 属性 | 类型 | 描述 |
| --- | --- | --- |
| `set` | `(value: boolean \| number \| string, options: SendDpOption) => Promise<boolean>` | 所有类型都有该方法，下发 DP 点，但需要根据功能点类型传入不同的值 |
| `on` | `1. (options: SendDpOption) => Promise<boolean><br>2. (idx: number, options: SendDpOption) => Promise<boolean>` | 只有 bool 类型和 bitmap 类型才有此方法，打开功能点或开启指定 bit 位 |
| `off` | `1. (options: SendDpOption) => Promise<boolean><br>2. (idx: number, options: SendDpOption) => Promise<boolean>` | 只有 bool 类型和 bitmap 类型才有此方法，关闭功能点或关闭指定 bit 位 |
| `toggle` | `1. (options: SendDpOption) => Promise<boolean><br>2. (idx: number, options: SendDpOption) => Promise<boolean>` | 只有 bool 类型和 bitmap 类型才有此方法，切换功能点或翻转指定 bit 位 |
| `inc` | `(step: number, options: SendDpOption) => Promise<boolean>` | 只有 value 类型才有此方法，根据当前功能点步长 step 进行递增， |
| `dec` | `(step: number, options: SendDpOption) => Promise<boolean>` | 只有 value 类型才有此方法，根据当前功能点步长 step 进行递减 |
| `prev` | `(options: SendDpOption) => Promise<boolean>` | 只有 enum 类型才有此方法，切换到前一个枚举值 |
| `next` | `(options: SendDpOption) => Promise<boolean>` | 只有 enum 类型才有此方法，切换到下一个枚举值 |
| `random` | `(options: SendDpOption) => Promise<boolean>` | 只有 enum 类型才有此方法，随机切换到一个枚举值 |

##### `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` CustomRawDpMap

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

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

##### `type` DpValue

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

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

##### `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` DpState

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

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

##### `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` 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 时才存在 |


### 示例代码

#### 控制指定设备的各类型 DP 功能点

```tsx
// devices/schema.ts — as const 是类型推导的基石，set 为通用方法，其余为类型专属快捷方法
import { useDevicesActions, useDevicesProps } from '@ray-js/panel-sdk';

export const schema = [
  { code: 'switch_led',  property: { type: 'bool' }, type: 'obj', mode: 'rw', id: 1, name: '开关' },
  { code: 'brightness',  property: { type: 'value', min: 10, max: 1000, step: 1 }, type: 'obj', mode: 'rw', id: 2, name: '亮度' },
  { code: 'work_mode',   property: { type: 'enum', range: ['white', 'colour'] }, type: 'obj', mode: 'rw', id: 3, name: '模式' },
  { code: 'fault',       property: { type: 'bitmap', maxlen: 8 }, type: 'obj', mode: 'ro', id: 4, name: '故障' },
  { code: 'colour_data', property: { type: 'string', maxlen: 255 }, type: 'obj', mode: 'rw', id: 5, name: '颜色' },
] as const;

export default function MultiDeviceControl() {
  const actions = useDevicesActions();
  // 推荐：精确选用需要的状态，避免无关变化引起无意义渲染
  const mainSwitch = useDevicesProps(props => props.main?.switch_led);

  const handleToggle = () => {
    // ✅ set — 所有类型通用
    actions.main?.switch_led.set(true);            // bool
    actions.main?.brightness.set(500);             // value
    actions.main?.work_mode.set('colour');         // enum（IDE 提示 'white' | 'colour'）
    actions.main?.fault.set(3);                    // number(bitmap)
    actions.main?.colour_data.set('000003e803e8'); // string

    // bool 专属：on / off / toggle
    actions.main?.switch_led.toggle();
    actions.main?.switch_led.on();
    actions.main?.switch_led.off();

    // value 专属：inc / dec（按 step 步进，自动 clamp 到 min~max）
    actions.main?.brightness.inc();               // +1（默认 step）
    actions.main?.brightness.dec(100);            // -100

    // enum 专属：prev / next / random
    actions.main?.work_mode.next();               // 切换到下一个枚举值
    actions.main?.work_mode.prev();

    // bitmap 专属：on(idx) / off(idx) / toggle(idx)
    actions.main?.fault.on(0);                    // 置位 bit 0
    actions.main?.fault.off(1);                   // 清除 bit 1
    actions.main?.fault.toggle(2);                // 翻转 bit 2
  };

  return (
    <View onClick={handleToggle}>
      <Text>主设备: {mainSwitch ? '开' : '关'}</Text>
    </View>
  );
}
```
