---
title: Usage
---

# Usage

## Create SDM

<Alert type="info">
The following directory contains all the files required for this chapter. You can also directly develop based on the [public-sdm](https://github.com/Tuya-Community/tuya-ray-materials/tree/main/template/PublicSdmTemplate) sample project.
</Alert>

<Tree.DirectoryTree
  multiple
  defaultExpandAll
  treeData={[
    {
      title: 'src',
      key: '0-0',
      children: [
        {
          title: 'devices',
          key: '0-0-0',
          isLeaf: false,
          children: [
            { title: 'index.ts', key: '0-0-0-1', isLeaf: true },
            { title: 'schema.ts', key: '0-0-0-2', isLeaf: true },
          ],
        },
        {
          title: 'pages',
          key: '0-0-1',
          isLeaf: false,
          children: [
            {
              title: 'home',
              key: '0-0-1-1',
              isLeaf: false,
              children: [{ title: 'index.tsx', key: '0-0-1-1-1', isLeaf: true }],
            },
          ],
        },
        { title: 'app.tsx', key: '0-0-2', isLeaf: true },
      ],
    },
    {
      title: 'typings',
      key: '0-1',
      children: [{ title: 'sdm.d.ts', key: '0-1-0', isLeaf: true }],
    },
  ]}
/>

### Generating Smart Device Model

<Callout type="info" emoji="ℹ️">
  This example file is located at devices/index.ts, and it is used to generate intelligent device models for use in subsequent business projects.
</Callout>

```typescript
import { SmartDeviceModel } from '@ray-js/panel-sdk';

// `SmartDevices` is defined in `typings/sdm.d.ts`. You can ignore this definition file if you do not write programs with TypeScript.
export const devices = {
  /**
   * A key named with a smart device name is recommended.
   */
  robot: new SmartDeviceModel<SmartDeviceSchema>(),
};

/**
 * Note: If SdmProvider is used, there is no need to manually call the init method.
 * SdmProvider will automatically call it and render the child components after the device initialization is complete.
 */
Object.keys(devices).forEach((k: keyof typeof devices) => {
  devices[k].init();
});
```

### Defining Smart Device Schema File

<Callout type="info" emoji="ℹ️">
  This example file is located at src/devices/schema.ts and is used to define the DP (Data Point) function descriptions of the intelligent device. It enables development based on the current intelligent device's functional definitions while adhering to TypeScript type constraints in subsequent business projects.
</Callout>

```typescript
/**
 * Schema of DPs in the SDM.
 */
export const defaultSchema = [
  {
    attr: 0,
    canTrigger: true,
    code: 'power',
    defaultRecommend: false,
    editPermission: false,
    executable: true,
    extContent: '',
    iconname: 'icon-dp_power2',
    id: 1,
    mode: 'rw',
    name: 'Switch',
    property: {
      type: 'bool',
    },
    type: 'obj',
  },
  {
    attr: 0,
    canTrigger: true,
    code: 'mode',
    defaultRecommend: false,
    editPermission: false,
    executable: true,
    extContent: '',
    iconname: 'icon-dp_mode',
    id: 3,
    mode: 'rw',
    name: 'Cleaning mode',
    property: {
      range: [
        'standby',
        'random',
        'smart',
        'wall_follow',
        'mop',
        'spiral',
        'left_spiral',
        'right_spiral',
        'right_bow',
        'left_bow',
        'partial_bow',
        'chargego',
      ],
      type: 'enum',
    },
    type: 'obj',
  },
] as const;
```

<Callout type="info" emoji="ℹ️">
  You can inject it into the project through the SDM tab in the Tuya MiniApp IDE device tool, as shown in the figure below.
</Callout>

<Callout type="warning" emoji="⚠️">
  Please ensure to add the `as const` assertion to the schema in order to enable proper type inference.
</Callout>

<Image src='/images/panel/virtual-device-sdm.en-US.png'/>

### Global Declaration of Smart Device Types

<Callout type="info" emoji="ℹ️">
  This example file is located at typings/sdm.d.ts and is used to globally declare type definitions related to SDM. It allows developers to easily access TS type hints for smart device-related Hooks in their projects. Non-TypeScript developers may ignore this type definition file.
</Callout>

<Callout type="warning" emoji="⚠️">
  Please note that this step must be performed after the completion of the smart device descriptor file in the previous step, otherwise it may result in failed TS type inference.
</Callout>

```typescript
import '@ray-js/panel-sdk';
import { GetStructuredDpState, GetStructuredActions } from '@ray-js/panel-sdk';

type SmartDeviceSchema = typeof import('@/devices/schema').defaultSchema; // 注意变量名
type SmartDeviceProtocols = typeof import('@/devices/protocols').protocols;
type SmartDevices = import('@ray-js/panel-sdk').SmartDeviceModel<SmartDeviceSchema>;

declare module '@ray-js/panel-sdk' {
  export const SdmProvider: React.FC<{
    value: SmartDeviceModel<SmartDeviceSchema>;
    children: React.ReactNode;
  }>;
  export type SmartDeviceInstanceData = {
    devInfo: ReturnType<SmartDevices['getDevInfo']>;
    dpSchema: ReturnType<SmartDevices['getDpSchema']>;
    network: ReturnType<SmartDevices['getNetwork']>;
    bluetooth: ReturnType<SmartDevices['getBluetooth']>;
  };
  export function useProps(): SmartDevices['model']['props'];
  export function useProps<Value extends any>(
    selector: (props?: SmartDevices['model']['props']) => Value,
    equalityFn?: (a: Value, b: Value) => boolean
  ): Value;
  export function useStructuredProps(): GetStructuredDpState<SmartDeviceProtocols>;
  export function useStructuredProps<Value extends any>(
    selector: (props?: GetStructuredDpState<SmartDeviceProtocols>) => Value,
    equalityFn?: (a: Value, b: Value) => boolean
  ): Value;
  export function useDevice(): SmartDeviceInstanceData;
  export function useDevice<Device extends any>(
    selector: (device: SmartDeviceInstanceData) => Device,
    equalityFn?: (a: Device, b: Device) => boolean
  ): Device;
  export function useActions(): SmartDevices['model']['actions'];
  export function useStructuredActions(): GetStructuredActions<SmartDeviceProtocols>;
}
```

## Use SDM

### Using SdmProvider in the Root Component

<Callout type="info" emoji="ℹ️">
  This example file is located at src/app.tsx, where the SdmProvider is used in the root component. It will wait for the initialization of the provided device to complete before rendering the child components. This ensures that the accompanying [SDM hooks](/en/miniapp/solution-panel/ability/common/sdm/hooks/useProps) can be used in any page component thereafter.
</Callout>

```tsx | pure
import React from 'react';
import 'ray';
import '@/i18n';
import { kit, SdmProvider } from '@ray-js/panel-sdk';
import { devices } from '@/devices';

const { initPanelEnvironment } = kit;

interface Props {
  children: React.ReactNode;
}

initPanelEnvironment({ useDefaultOffline: true });

export default class App extends React.Component<Props> {
  onLaunch() {
    console.info('=== App onLaunch');
  }

  render() {
    return (
      <SdmProvider value={devices.robot}>{this.props.children}</SdmProvider>
    );
  }
}
```

### Controlling Devices through SDM

<Callout type="info" emoji="ℹ️">
  This example file is located at src/pages/home/index.tsx. It controls the on/off state of smart devices and retrieves real-time values using the accompanying useActions hooks.
</Callout>

```jsx | pure
import React from 'react';
import { Button, View } from '@ray-js/ray';
import { useActions, useProps } from '@ray-js/panel-sdk';
import { devices } from '@/devices';

export default function Home() {
  const power = useProps(props => props.power);
  const actions = useActions();
  return (
    <View>
      <Button onClick={() => actions.power.toggle()}>
        Tap Me and switch between on and off states.
      </Button>
      <Text>{`Power Status: ${power}`}</Text>
    </View>
  );
}
```

## Multi-Device

To manage multiple devices in the same Mini Program, use the **Multi-Device Management** capability: inject `SmartDevicesManager` via `SdmProvider`'s `deviceManager` and use multi-device Hooks (`useDevices`, `useDevicesProps`, `useDevicesActions`, etc.). See [Multi-Device Management - Usage](/en/miniapp/solution-panel/ability/common/multi-device/usage) and [Multi-Device Management - Hooks](/en/miniapp/solution-panel/ability/common/multi-device/hooks/useDevices).
