前提条件

构建内容

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

学习内容

所需条件

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

产品名称

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. 进入 IoT 平台,点击左侧 产品菜单,产品开发,创建产品,选择 标准类目 -> 照明 -> 户外灯具 -> 露营灯 -> 太阳能二路,如下图所示:

  1. 选择功能点,在这里我们根据实际场景把对应的开关功能点选上,这里可直接使用默认 dp 配置点击确定,对于定义来说,它就是一个标准的照明灯具设备,具体如下图所示:

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

这部分我们在 小程序开发者 平台上进行操作,注册登录 小程序开发者平台 进行操作。

详细的操作路径可参考 面板小程序 - 创建面板小程序

IDE 基于模板创建项目工程

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

详细的操作路径可参考 面板小程序 - 初始化项目工程

在项目中创建一个 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 云端同步来实现:

设置 synchronizeDevProperty 为 true

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

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

下发上报响应

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

const actions = useActions();

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

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