使用

创建 SDM

Info

以下目录包含了本章节所需要涉及到的所有文件,也可以直接基于 public-sdm 示例项目进行开发

  • src
    • devices
      • index.ts
      • schema.ts
    • pages
      • home
        • index.tsx
    • app.tsx
  • typings
    • sdm.d.ts

生成智能设备模型

Info

该示例文件位于 devices/index.ts,用于生成智能设备模型以供后续业务项目中使用

import { SmartDeviceModel, SmartGroupModel, SmartDeviceSchema } from '@ray-js/panel-sdk';
import { getLaunchOptionsSync } from '@ray-js/ray';

// SmartDeviceSchema 定义来自于 typings/sdm.d.ts,非 TypeScript 开发者可忽略
export const devices = {
  /**
   * 此处建议以智能设备的名称作为键名赋值,
   * 如果想要默认支持基础群组功能,则可以判断当前是否为群组环境来选择使用的智能模型以默认适配
   */
  robot: isGroupDevice
    ? new SmartGroupModel<SmartDeviceSchema>(options)
    : new SmartDeviceModel<SmartDeviceSchema>(options),
};

/**
 * 注意,如果使用了 SdmProvider 则无需手动调用 init 方法,SdmProvider 会自动调用并在设备初始化完毕后再渲染子组件
 */
Object.keys(devices).forEach((k: keyof typeof devices) => {
  devices[k].init();
});

定义智能设备描述文件

Info

该示例文件位于 src/devices/schema.ts,用于定义智能设备的 DP 功能点描述,以便后续业务中可以根据 TS 的类型约束,围绕当前智能设备的功能定义进行开发

/**
 * 智能设备模型的 DP 功能点描述
 */
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: '开关',
    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: '清扫模式',
    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;
Info

可通过 Tuya MiniApp IDE 中设备工具里的智能设备模型 Tab 来注入到项目中,详见下图

Warning

请注意给 schema 加上 as const 断言以便能够正常进行类型推导

全局声明智能设备类型

Info

该示例文件位于 typings/sdm.d.ts,用于全局声明 SDM 相关的类型定义,方便开发者在项目中能一键获得智能设备相关配套 Hooks 的 TS 类型提示,非 TypeScript 开发者可忽略该类型定义文件

Warning

请注意该步骤必须在上一步智能设备描述文件定义完成后进行,否则会导致 TS 类型推导失败

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>;
}

使用 SDM

根组件使用 SdmProvider

Info

该示例文件位于 src/app.tsx,在根组件中使用了 SdmProvider,会等待传入的设备初始化完毕以后再进行渲染子组件,以便后续在任意页面组件中能使用 SDM 的配套 Hooks

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>
    );
  }
}

通过 SDM 控制设备

Info

该示例文件位于 src/pages/home/index.tsx,通过配套的 useActions hooks 来控制智能设备的开关并实时获取开关的值

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()}>
        点击我切换设备开关状态
      </Button>
      <Text>{`开关状态: ${power}`}</Text>
    </View>
  );
}

多设备场景

若需在同一小程序内管理多台设备,请使用 多设备管理 能力:通过 SdmProvider 的 deviceManager 注入 SmartDevicesManager,并使用多设备 Hooks(useDevices、useDevicesProps、useDevicesActions 等)。详见 多设备管理 - 使用 与 多设备管理 - Hooks。