1. 准备工作
前提条件
- 已阅读 Ray 新手村任务,了解 Ray 框架的基础知识
- 已阅读 使用 Ray 开发万能面板,了解 Ray 面板开发的基础知识
构建内容
在此 Codelab 中,您将利用面板小程序开发构建出一个支持一键执行及自动化的无线开关面板,通过基于场景联动的能力,实现以下能力:
- 一键执行:在设备面板小程序中点击 UI 按钮时,一键执行触发其他设备的功能
- 自动化:实现在实体按键操作(单击、双击、长按)后批量控制多个关联设备的能力。
学习内容
- 如何创建一个无线开关产品
- 如何使用一键执行模板快速初始化一个面板项目
- 如何实现在面板小程序中动态渲染按键列表及其绑定状态
- 如何实现在面板小程序中点击 UI 按钮时,一键控制其他关联的设备
- 如何实现在实体按键操作(单击、双击、长按)后批量控制多个关联设备。
所需条件
详见 面板小程序 - 搭建环境
- 智能生活 App
- Tuya MiniApp Tools
- NVM 及 Node 开发环境(建议使用 16.x 系列版本)
- Yarn 依赖管理工具
2. 需求分析
产品名称
无线开关
注意:本文介绍的一键执行场景功能必须在有网的环境下才可以使用,如 Zigbee 设备必须在网关下才可以使用。
需求原型
首页
:- 顶部展现了当前设备的图片,中心区域展示设备的按键列表信息,并展示每个按键是否已经绑定了对应的一键执行场景。
- 点击已绑定一键执行按键会展示确认手动执行的二次确认框。
- 右滑已绑定的一键执行按键的列表项并点击解绑会打开解绑的二次确认框。
- 点击已绑定的一键执行按键的右下角的三角形按钮会跳转进入
编辑一键执行页
。
- 点击未绑定一键执行的按键展示选择触发开关场景的按键条件,选择好触发条件后则会跳转进入
选择联动
页面。
选择联动页
:- 列表中会展示支持给当前开关按键绑定的所有一键执行类型的场景联动。
- 在未选中状态,点击右下角的添加按钮,会跳转
创建一键执行页
。
- 在选中状态,点击右下角的添加按钮,会跳转
编辑一键执行页
。
- 点击确认会保存当前选择的状态,并返回
首页
。
功能汇总
当前无线开关需要的功能点见下,其中场景按键 DP 可以根据实际设备的长度自行删减,但注意必须为 switch_type_${btnId} 这种格式。
DP ID | 功能点名称 | 标识符 | 数据传输类型 | 数据类型 | 功能点属性 |
1 | 按键 1 | switch_type_1 | 只上报(ro) | enum | 枚举值: single_click, double_click, long_press |
2 | 按键 2 | switch_type_2 | 只上报(ro) | enum | 枚举值: single_click, double_click, long_press |
3 | 按键 3 | switch_type_3 | 只上报(ro) | enum | 枚举值: single_click, double_click, long_press |
4 | 按键 4 | switch_type_4 | 只上报(ro) | enum | 枚举值: single_click, double_click, long_press |
3. 创建产品
首先需要创建一个无线开关产品,定义产品有哪些功能点,然后面板中再根据这些功能点进行实现。
- 进入 IoT 平台,点击左侧 产品菜单,产品开发,创建产品,选择
标准类目 -> 电工 -> 无线开关
,如下图所示:
- 选择功能点,在这里我们根据实际场景把对应的开关功能点选上,在当前 Codelab 中我们选择了 switch_type_1 -> switch_type_4 四个开关功能点,对于定义来说,它就是一个存在四个按键的四路无线开关设备,具体如下图所示:
🎉 在这一步,我们成功完成创建了一个无线开关产品。
4. 创建项目
开发者平台创建面板小程序
这部分我们在 小程序开发者
平台上进行操作,注册登录 小程序开发者平台 进行操作。
详细的操作路径可参考 面板小程序 - 创建面板小程序
IDE 基于模板创建项目工程
这部分我们在 Tuya MiniApp Tools
上进行操作,打开 IDE 创建一个基于无线开关一键执行模板的面板小程序项目。
详细的操作路径可参考 面板小程序 - 初始化项目工程
也可以前往 Github 仓库进行手动 clone
5. 动态渲染按键列表
- 首先我们需要根据 DP 功能点的定义,动态渲染开关按键列表,这里我们可以通过
SDM
的SmartDeviceSchema
类型定义来获取到当前设备的 DP 功能点列表,然后根据switch_type_${no}
的 DP 功能点命名规则来匹配获取到当前设备的按键列表,如下代码所示:
import { SmartDeviceSchema } from 'typings/sdm';
export const getSceneDps = (schema: SmartDeviceSchema) => {
if (!Array.isArray(schema)) return [];
return schema.map(s => s.code.match(/switch_type_(\d+)/)?.[1]);
};
- 然后我们在
首页
页面中根据getSceneDps
函数获取到的按键列表,动态渲染开关按键列表。
import React from 'react';
import { Image, ScrollView, View } from '@ray-js/ray';
import { useCreation } from 'ahooks';
import { useSelector } from 'react-redux';
import { DpSchema, useDevice } from '@ray-js/panel-sdk';
import { TopBar } from '@/components';
import { selectBindTapToRunRules } from '@/redux/modules/sceneSlice';
import { getSceneDps } from '@/utils/getSceneDps';
import { Scene } from './components/scene';
import styles from './index.module.less';
export function Home() {
const schema = useDevice(d => d.devInfo.schema);
const dpSchema = useDevice(d => d.dpSchema);
const devInfo = useDevice(d => d.devInfo);
const bindTapToRunRules = useSelector(selectBindTapToRunRules);
const sceneDpList = useCreation(() => {
return getSceneDps(schema).map(btnId => {
// 一些暂时可忽略的逻辑代码
});
}, [schema, bindTapToRunRules]);
return (
<View className={styles.view}>
<TopBar />
<View className={styles.content}>
<View className={styles.main}>
<View className={styles.logo}>
<Image src={devInfo.iconUrl} />
</View>
</View>
<ScrollView
style={{ maxHeight: '360px', height: 'auto' }}
className={styles.card}
refresherTriggered
scrollY
>
<Scene sceneDpList={sceneDpList} />
</ScrollView>
</View>
</View>
);
}
细心的你可能已经发现了,在我们通过 getSceneDps 函数返回的数据后,注释忽略了 `一些暂时可忽略的逻辑代码`,这些会在开关按键设备绑定状态章节中详细讲解。
👉 立即免费领取开发资源,体验涂鸦 MiniApp 小程序开发。