---
name: "createDpKit"
mode: "api"
versionRequirements:
  - { name: "@ray-js/panel-sdk", version: "1.7.0" }
title: "createDpKit - Create a dp-kit instance"
summary: "createDpKit is a function provided by @ray-js/panel-sdk for creating a dp-kit instance. Key capabilities include customizing parser/formatter through protocols, automatically parsing and formatting complex DP types such as colour_data into hue/saturation/value, sendDpOption support for throttle, debounce, delay, checkRepeat, and ordered command sending, immediate UI updates after command sending without waiting for reporting, ignoreDpDataResponse to ignore device reporting responses with whiteDpCodes, timeout, and customRule, synchronizeDevProperty to sync cloud DP status with blackDpCodes and defaultState, and onBeforeSendDp/onAfterSendDp hooks. Use it with useStructuredProps/useStructuredActions. typings/sdm.d.ts provides global TypeScript declarations."
---

## createDpKit

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

> 💡 Pass the interceptors returned by createDpKit into SmartDeviceModel constructor options,
> and when used with useStructuredProps / useStructuredActions, call init after device initialization.

### Description

Create a DP protocol suite that provides structured DP parsing, send interception, and enhancements such as throttling/debouncing

### Parameters

`Params`

| Parameter | Type | Required | Description |
| --- | --- | --- | --- |
| `option` | `CreateDpKitOptions` | No | dp-kit configuration options |

### Return Value

Type: `CreateDpKitResult`

dp-kit instance, including methods such as init, interceptors, and destroy

**`type` CreateDpKitResult**

| Property | Type | Description |
| --- | --- | --- |
| `init` | `(device: any) => void` | Initialize device state; when used with useStructuredProps, call after the device model has finished initializing. |
| `interceptors` | `Record<string, any>` | dp-kit default interceptor configuration |
| `onDeviceInfoUpdated` | `(ctx: any) => (next: (data: any) => any) => (data: any) => any` | dp-kit onDeviceInfoUpdated interceptor; can be used standalone if needed. |
| `onDpDataChange` | `(ctx: any) => (next: (data: any) => any) => (data: any) => any` | dp-kit onDpDataChange interceptor; can be used standalone if needed. |
| `publishDps` | `(ctx: any) => (next: (dpState: Record<string, any>, options?: SendDpOption) => any) => (dpState: Record<string, any>, options?: SendDpOption) => any` | dp-kit publishDps interceptor; can be used standalone if needed. |
| `destroy` | `() => void` | Destroy dp-kit and clean up resources such as flush timers and throttling/debouncing maps. Should be called when SmartDeviceModel is destroyed (e.g., in SdmProvider's useEffect cleanup). |

### Referenced Types

##### `type` CreateDpKitOptions

createDpKit configuration options that unify protocol parsing, global dispatch options, and pre/post hooks.

| Property | Type | Description |
| --- | --- | --- |
| `protocols` | `Record<string, CustomRawDpMap>` | DP protocol mapping table that decomposes composite string-type DPs (e.g., colour_data) into structured objects. Keys are dpCode; values are custom Transformers.  Implement parser/formatter: `{ colour_data: new ColourTransformer() }`  - parser(raw: string) => T — Parse the raw string reported by the device into a structured object - formatter(data: T) => string — Serialize the structured object into a string to send to the device  After registration, you can read/write structured data via useStructuredProps / useStructuredActions. |
| `sendDpOption` | `SendDpOption` | DP dispatch options |
| `onBeforeSendDp` | `(dpState: DpState) => any` | Pre-dispatch hook for DP |
| `onAfterSendDp` | `(dpState: DpState) => any` | Pre-dispatch hook for DP |

##### `type` CreateDpKitResult

The result of createDpKit, containing a set of interceptors that can be attached directly to SmartDeviceModel, plus the `init` / `destroy` lifecycle methods required to initialize structured DP state.

| Property | Type | Description |
| --- | --- | --- |
| `init` | `(device: any) => void` | Initialize device state; when used with useStructuredProps, call after the device model has finished initializing. |
| `interceptors` | `Record<string, any>` | dp-kit default interceptor configuration |
| `onDeviceInfoUpdated` | `(ctx: any) => (next: (data: any) => any) => (data: any) => any` | dp-kit onDeviceInfoUpdated interceptor; can be used standalone if needed. |
| `onDpDataChange` | `(ctx: any) => (next: (data: any) => any) => (data: any) => any` | dp-kit onDpDataChange interceptor; can be used standalone if needed. |
| `publishDps` | `(ctx: any) => (next: (dpState: Record<string, any>, options?: SendDpOption) => any) => (dpState: Record<string, any>, options?: SendDpOption) => any` | dp-kit publishDps interceptor; can be used standalone if needed. |
| `destroy` | `() => void` | Destroy dp-kit and clean up resources such as flush timers and throttling/debouncing maps. Should be called when SmartDeviceModel is destroyed (e.g., in SdmProvider's useEffect cleanup). |

##### `type` CustomRawDpMap

Custom DP protocol converter for transforming between raw DP strings and structured objects.
Suitable for composite DPs of type raw/string (e.g., a light's colour_data "00ff003e8"),
splitting a single string into multiple semantic fields (e.g., { hue, saturation, value }).

| Property | Type | Description |
| --- | --- | --- |
| `parser` | `(dpValue: string) => any` | Parse the raw DP string reported by the device into a structured object |
| `formatter` | `(parsedDpValue: any) => string` | Serialize the structured object into a DP string to be sent to the device |

##### `type` SendDpOption

DP send options. Can be used as the global default configuration for createDpKit, and can also be overridden in a single publishDps/action call.
The global `sendDpOption` suits product-level defaults;
options passed for a single send are suitable for temporarily overriding throttling, debouncing, protocol parsing, or optimistic update strategies.
Note: requires the dp-kit interceptor.

| Property | Type | Since | Description |
| --- | --- | --- | --- |
| `immediate` | `boolean` | - | Whether to trigger a state update immediately; requires the dp-kit interceptor |
| `ignoreDpDataResponse` | `boolean \| IgnoreDpChangeInterceptorOptions` | `1.11.0` | Whether to ignore DP reports; default false |
| `synchronizeDevProperty` | `boolean \| DevPropInterceptorOptions` | `1.11.0` | Whether to sync dpData with cloud device properties; default false |
| `ordered` | `boolean` | - | Whether to send multiple DPs in the order of the object’s keys; requires the dp-kit interceptor; default false |
| `checkRepeat` | `boolean` | - | Whether to check for duplicate values and skip sending; requires the dp-kit interceptor; default false Compared with the current `dpState`; duplicates are detected and not sent |
| `delay` | `number` | - | Delayed send; requires the dp-kit interceptor; default 0, in ms |
| `throttle` | `number` | - | Send throttling (conflicts with debounce); requires the dp-kit interceptor; default 0, in ms |
| `debounce` | `number` | - | Send debounce (conflicts with throttle); requires the dp-kit interceptor; default 0, in ms |
| `protocols` | `Record<string, CustomRawDpMap>` | - | A per-call DP protocol converter; requires the dp-kit interceptor. The key is the dpCode and the value is a `{ parser, formatter }` object: - parser(dpValue: string) => any — parses the raw DP string into a structured object - formatter(parsedValue: any) => string — serializes the structured object into a DP string Affects only this invocation and does not override the global protocols configuration in createDpKit |

##### `type` DpState

Datapoint status object, where the key is the datapoint code and the value is the datapoint value.

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

##### `type` IgnoreDpChangeInterceptorOptions

Configuration option to ignore the DP data change interceptor

Used to configure the debounce mechanism for DP reporting events on the device panel, preventing immediate responses after panel operations from affecting user experience or business logic

| Property | Type | Description |
| --- | --- | --- |
| `whiteDpCodes` | `string[]` | DP whitelist; reports will not be ignored |
| `timeout` | `number` | Debounce timeout check, in milliseconds, default 5000 - The maximum time between sending a DP from the panel and receiving the DP reply; dpDataChange is triggered only if this is exceeded. - Used to debounce DP reporting events |
| `customRule` | `(dpState: DpState, lastSendTimestamp: number) => boolean` | Custom ignore rules > Highest priority; when configured, whiteDpCodes and timeout become ineffective |

##### `type` DevPropInterceptorOptions

| Property | Type | Description |
| --- | --- | --- |
| `blackDpCodes` | `string[]` | DP blacklist; will not be synchronized to the cloud |
| `defaultState` | `DpState` | Default device state on first entry; supports async initialization |
| `throttle` | `number` | Send throttling, in milliseconds, defaults to 0 If set to 0, throttling is disabled. |

##### `type` DpValue

Datapoint value type, which can be boolean, number, or string.

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


### Examples

#### Basic usage.

```ts
import { SmartDeviceModel, createDpKit } from '@ray-js/panel-sdk';

const schema = [
  { code: 'switch_1', type: 'bool' },
  { code: 'colour_data', type: 'raw' },
] as const;

const dpKit = createDpKit<typeof schema>({
  protocols: {
    colour_data: {
      parser: raw => JSON.parse(raw),
      formatter: structured => JSON.stringify(structured),
    },
  },
});

const sdm = new SmartDeviceModel<typeof schema>({
  interceptors: dpKit.interceptors,
});

await sdm.init();
dpKit.init(sdm);
```

#### Includes protocol parsing and throttling

```ts
const dpKit = createDpKit<typeof schema>({
  protocols: {
    colour_data: {
      parser: raw => JSON.parse(raw),
      formatter: value => JSON.stringify(value),
    },
  },
  sendDpOption: {
    throttle: 300,
  },
});

const device = new SmartDeviceModel<typeof schema>({
  interceptors: dpKit.interceptors,
});

await device.init();
dpKit.init(device);

// All subsequent sends inherit 300ms throttling
await device.publishDps({
  colour_data: { hue: 240, saturation: 1000, value: 1000 },
});
```

#### Ignore device report responses

```ts
const dpKit = createDpKit<typeof schema>({
  sendDpOption: {
    immediate: true,
    ignoreDpDataResponse: {
      timeout: 5000,
      whiteDpCodes: ['switch_1'],
    },
  },
});

const device = new SmartDeviceModel<typeof schema>({
  interceptors: dpKit.interceptors,
});
```

#### Use with hooks

```tsx
import { useStructuredActions, useStructuredProps } from '@ray-js/panel-sdk';

const colour = useStructuredProps(props => props.colour_data);
const actions = useStructuredActions();

actions.colour_data.set({
  hue: colour.hue,
  saturation: colour.saturation,
  value: 800,
});
```
