前提条件

构建内容

在 Codelab 中,您可以利用面板小程序开发构建出一个基于 Beacon 设备面板模板的 Beacon 设备面板,基于 DP-Kit 拦截器的能力,实现以下能力:

学习内容

所需条件

详见 面板小程序 > 搭建环境

产品名称:Beacon 灯具

需求原型

你需要为 Beacon 灯具设备编写一个控制面板,UI 原型如下图所示:

拥有开关、电池电量显示、色温色盘、亮度滑动条。其中电量数据为设备主动上报获取,其他 DP 数据均无上报。

功能汇总

当前面板需要的功能点见下:

DP ID

功能点名称

标识符

数据传输类型

数据类型

功能点属性

1

开关

switch_led

可下发可上报(rw)

布尔(Boolean)

{"type":"bool"}

3

亮度值

bright_value

只下发(wr)

数值(Value)

{"min":10,"max":1000,"step":1,"unit":"","scale":0,"type":"value"}

4

冷暖值

temp_value

只下发(wr)

数值(Value)

{"min":0,"max":1000,"step":1,"unit":"","scale":0,"type":"value"}

62

电池电量状态

battery_state

可下发可上报(rw)

枚举(Enum)

{"range":["low","middle","high"],"type":"enum"}

首先需要创建一个照明标准产品,定义产品有哪些功能点,然后再在面板中一一实现这些功能点。

注册登录 涂鸦开发者平台,并在平台创建产品:

  1. 单击页面左侧 产品 > 产品开发,在 产品开发 页面单击 创建产品
  2. 标准类目 下选择 照明,产品品类选择 户外灯具 > 露营灯
  3. 选择智能化方式,产品方案选择为 太阳能二路灯,并完善产品信息。
  4. 单击 创建产品 按钮,完成产品创建。
  5. 产品创建完成后,进入到 添加标准功能 页面,根据实际场景选择对应的开关功能点,可以直接使用默认 DP 配置,然后单击 确定,即定义一个标准的照明灯具设备,如下所示:

开发者平台创建面板小程序

面板小程序的开发在 小程序开发者 平台上进行操作,首先请前往 小程序开发者平台 完成平台的注册登录。

详细操作步骤可以参考 面板小程序 > 创建面板小程序

IDE 基于模板创建项目工程

打开 IDE 创建一个基于 Beacon 设备面板模版的面板小程序项目,需要在 Tuya MiniApp IDE 上进行操作。

详细操作步骤可以参考 面板小程序 > 初始化项目工程

在项目中创建一个 DP-Kit 拦截器,模版代码 src/devices/index

export const dpKit = createDpKit<SmartDeviceSchema>({});

export const devices = {
  lamp: new SmartDeviceModel<SmartDeviceSchema>({
    // 配置 DP-Kit 拦截器到 SDM 模型
    interceptors: dpKit.interceptors,
  }),
};

同时,需要在设备模型初始化完成后,初始化 DP-Kit:

// App 启动回调
onLaunch() {
  devices.lamp.init();
  devices.lamp.onInitialized(res => {
    dpKit.init(devices.lamp); // 初始化 DP-Kit
  });
}

这样就完成了 SDM 模型的 DP-Kit 基础配置。

Beacon 类型设备的特点是几乎只接受 DP 下发,而不会上报,所以用以往的受控模式来编写面板逻辑会导致 UI 界面无响应,可以使用 DP-Kit 配置下发立即响应模式来解决。

只需在 sendDpOption 中,设置 immediatetrue 即可。

export const dpKit = createDpKit<SmartDeviceSchema>({
  sendDpOption: {
    immediate: true, // 启用 DP 下发立即响应,而不受控于设备
  },
});

当面板中调用 actions 下发时,面板会立即进行响应,而不等待设备 DP 上报,例如:

const actions = useActions();
actions.bright_value.set(100); // 下发亮度后,面板立即响应

在虚拟设备调试时,会受到设备上报影响,可以通过配置拦截器实现忽略设备上报:

export const dpKit = createDpKit<SmartDeviceSchema>({
  // 启动忽略设备上报
  ignoreDpDataResponse: {
    debug: true, // 启用日志查看
  },
});

此时当设备上报任何 DP,面板中通过 useProps 获取数据展示的 UI 都不会进行响应更新。

但对于部分特殊的 DP,例如电量,还是需要监听设备上报数据,可以通过配置白名单实现:

export const dpKit = createDpKit<SmartDeviceSchema>({
  // 启动忽略设备上报
  ignoreDpDataResponse: {
    debug: true, // 启用日志查看
    whiteDpCodes: [dpCodes.batteryStateCode], // 需要响应电量 DP 的上报
  },
});

当设备上报电量时,通过 useProps 获取数据展示的电池 UI 会进行更新,例如:

const battery_state = useProps(state => state?.battery_state);

// 设备上报 battery_state 时更新
<Battery value={battery_state} />

由于 Beacon 设备不会上报 DP 数据,并且当配置了 忽略设备 DP 上报 模式后,首次进入面板的初始状态是获取不到的,可以通过配置 DP 云端同步来实现:

设置 synchronizeDevPropertytrue

export const dpKit = createDpKit<SmartDeviceSchema>({
  sendDpOption: {
    // 将下发 DP 同步至云端设备数据存储
    synchronizeDevProperty: {
      // 云端数据为空时的默认值
      defaultState: {
        [dpCodes.brightCode]: 1000,
        [dpCodes.temperatureCode]: 1000,
      },
    },
    // 或 synchronizeDevProperty: true
  },
});

当面板下发 DP 时,会将 DP 数据保存至云端设备数据,当退出面板再次进入时,会自动拉取云端 DP 数据注入到面板中作为初始状态。同时支持配置当云端数据为空时的默认值。

同时 defaultState 支持函数式初始化,例如亮度默认值为产品配置的最大值:

export const dpKit = createDpKit<SmartDeviceSchema>({
  sendDpOption: {
    // 将下发 DP 同步至云端设备数据存储
    synchronizeDevProperty: {
      // 云端数据为空时的默认值
      async defaultState (schema) {
        // 或接口请求
        const brightSchema = schema.find(item => item.code === dpCodes.brightCode)
        return {
          [dpCodes.brightCode]: brightSchema.max || 1000,
          [dpCodes.temperatureCode]: 1000,
        }
      },
    },
  },
});

下发上报响应

配置完成后(以上配置在模版代码中已内置支持),使用 SDM actions 进行下发 DP:

const actions = useActions();

// 色盘拖动时调用
actions.temp_value.set(100);

单击开关、操作亮度滑动条,查看 Console 调试器日志上报: