本文档面向已经了解 面板小程序开发
的开发者,你需要充分的了解什么是面板小程序
产品功能
若您对上述概念有所疑问,我们推荐你去看一些预备知识。如果您已了解,可跳过本文。
面板作为 IoT 智能设备在 App 终端上的产品形态,创建产品之前,首先来了解一下什么是面板,以及和产品、设备之间的关系。
面板
是运行在 智能生活 App
、OEM App(涂鸦定制 App)
上的界面交互程序,用于控制 智能设备
的运行,展示 智能设备
实时状态。产品
将 面板
与 智能设备
联系起来,产品描述了其具备的功能、在 App 上面板显示的名称、智能设备拥有的功能点等。智能设备
是搭载了 涂鸦智能模组
的设备,通常在设备上都会贴有一张二维码,使用 智能生活 App
扫描二维码,即可在 App 中获取并安装该设备的控制 面板
。产品
、面板
、设备
之间的关系可参考下图。电工模板使用 SDM(Smart Device Model)
开发,关于 SDM
相关可以 查看 SDM 文档
产品名称:通用电工插座
提供插座的打开与关闭的基本功能,并提供关闭倒计时、增加电量、更新当前电流、功率参数等功能,根据以下通用电工的开发教程帮助您开发面板小程序去控制插座。
首页
点击中间按钮切换 switch_1
开关状态。首页
页面展示倒计时提示,根据开关状态、手机系统的 24 小时制或 12 小时制、countdown_1
的值来显示对应的提示文案,若未设置倒计时则不展示。点击首页底部倒计时
弹出倒计时提示框组件来设置倒计时,若未设置则展示设置倒计时的组件,若已设置则可关闭倒计时。 点击首页底部设置
进入设置页面,可以对除 switch_1
、countdown_1
的所有 可下发可上报(rw)
功能进行设置。 当前电工插座模板必须的功能点:
switch_1,
countdown_1,
参数 | 取值 |
dpid | 1 |
code | switch_1 |
type | 布尔型(Bool) |
mode | 可下发可上报(rw) |
参数 | 取值 |
dpid | 9 |
code | countdown_1 |
type | 数值型(Value) |
mode | 可下发可上报(rw) |
property | 数值范围: 0-86400, 间距: 1, 倍数: 0, 单位: s |
上面为首页
需求必须的功能点
,设置页功能点这里不做介绍。
首先需要创建一个电工类产品,定义产品有哪些功能点,然后面板中再根据这些功能点一一实现。
进入IoT 平台,点击左侧产品菜单,产品开发,创建产品,选择标准类目 -> 电工 -> 插座
:
选择功能点,这里我们只需要默认的标准功能即可。
🎉 在这一步,我们创建了一个名为 PublicSocket
的电工插座产品。
这部分我们在 小程序开发者
平台上进行操作,注册登录 小程序开发者平台。
打开 IDE,选择新建,输入项目名称
,关联创建的面板小程序
,选择单插产品
,然后点击下一步
。
在下一步中,找到电工单插模板,并完成创建项目
此时,回到项目管理列表,选择刚创建好的项目,进入后,即可进行预览并开发。
上面的步骤我们已经初始化好了一个面板小程序
的开发模板,下面我们介绍下工程目录。
├── src
│ ├── app.config.ts # 自动生成配置
│ ├── app.tsx # App 根组件
│ ├── components # 组件目录
│ ├── constant # 常量目录
│ ├── devices # 智能设备模型目录
│ │ ├── index.ts # 定义并导出智能设备模型
│ │ └── schema.ts # 当前智能设备 DP 功能点描述,IDE 可自动生成
│ ├── global.config.ts
│ ├── hooks # 自定义 hooks 目录
│ ├── i18n # 多语言目录
│ ├── pages # 页面目录
│ └── routes.config.ts # 路由配置
│─── typings #业务类型定义目录
│ └── sdm.d.ts #智能设备类型定义文件
IDE
生成 SDM schema
到项目。生成 SDM schema
至项目中,可以查看 src/devices/schema.ts
export const defaultSchema = [
{
attr: 128,
canTrigger: true,
code: 'switch_1',
defaultRecommend: false,
editPermission: false,
executable: true,
extContent: '',
iconname: 'icon-dp_power2',
id: 1,
mode: 'rw',
name: '开关1',
property: {
type: 'bool',
},
type: 'obj',
},
{
attr: 640,
canTrigger: true,
code: 'countdown_1',
defaultRecommend: true,
editPermission: false,
executable: true,
extContent: '',
iconname: 'icon-dp_time2',
id: 9,
mode: 'rw',
name: '开关1倒计时',
property: {
unit: 's',
min: 0,
max: 86400,
scale: 0,
step: 1,
type: 'value',
},
type: 'obj',
},
// ...
];
首页
点击中间按钮切换 switch_1
开关状态分析需求:
开关按钮
。switch_1
下发的值展示不同按钮图片。开关
组件触发事件,上报「开」「关」的 dp 值。switch_1
,可作为属性传入组件。useProps
获取实时下发的 dp
值。示例:import React from 'react';
import { View } from '@ray-js/ray';
import { useProps } from '@ray-js/sdm-react';
export default function () {
const switch_1 = useProps((dpState) => dpState.switch_1);
return (
<View style={{ flex: 1 }}>
<View>switch_1: {switch_1}</View>
</View>
);
}
useActions
获取dp
上报的行为示例:import React from 'react';
import { View } from '@ray-js/ray';
import { useActions } from '@ray-js/sdm-react';
export default function () {
const actions = useActions();
return (
<View style={{ flex: 1 }}>
<Button
onClick={() => {
actions.switch_1.set(false);
}}
>
change action
</Button>
</View>
);
}
根据上述分析,我们来实现开关组件。
import React from 'react';
import clsx from 'clsx';
import { View } from '@ray-js/ray';
import { DpBooleanAction } from '@tuya-miniapp/sdm';
import { useProps, useActions } from '@ray-js/sdm-react';
import { Icon } from '@/components/icon';
import { icons } from '@/res';
import styles from './index.module.less';
export interface Props {
dpCode: string;
}
export const PowerButton = React.memo<Props>(props => {
const { dpCode } = props;
const value = useProps(dpState => dpState[dpCode]);
const actions = useActions();
if (!dpCode || typeof value !== 'boolean') {
return null;
}
const action = actions[dpCode] as DpBooleanAction;
return (
<View className={styles['power-button']} onClick={action.toggle}>
<View
className={clsx(styles['power-button-content'], {
[`${styles['power-button-off']}`]: !value,
})}
/>
<Icon
className={styles['power-button-icon']}
d={icons.power}
size="34px"
fill={value ? '#ef550d' : '#ffffff'}
/>
</View>
);
});
我们实现了 PowerButton
组件,下面的代码就可以在首页引入,并传入开关的 dp code
,下面修改首页的代码。
import React from 'react';
import { setNavigationBarTitle, View } from '@ray-js/ray';
import { useDevice } from '@ray-js/sdm-react';
import { PowerButton } from '@/components';
import styles from './index.module.less';
export default function Home() {
const deviceName = useDevice((d) => d.devInfo.name);
React.useEffect(() => {
setNavigationBarTitle({ title: deviceName });
}, [deviceName]);
return (
<View className={styles.view}>
<View className={styles.content}>
<View className={styles['space-between']}>
<PowerButton dpCode="switch_1" />
</View>
</View>
</View>
);
}
引入了代码之后,我们的首页有了一个可操控的按钮,这时我们可以修改 IDE
右侧控制面板 -> 1.开关 -> false/true
进行虚拟面板dp点的下发与上报
,也可以点击我们刚刚完成的组件,查看IDE 控制面板的状态
来验证我们的产品功能。
首页
页面展示倒计时提示,根据开关状态、手机系统的 24 小时制或 12 小时制、countdown_1
的值来显示对应的提示文案,若未设置倒计时则不展示。开关状态 switch_1 及倒计时 countdown_1
状态下发的值来控制展示内容。点击首页底部倒计时
弹出倒计时提示来设置倒计时,若未设置则展示设置倒计时的组件,若已设置则可关闭倒计时。倒计时 countdown_1
状态下发的值来控制展示内容。useActions
上报 倒计时 countdown_1
的状态。点击首页底部设置
进入设置页面,可以对除 switch_1
、countdown_1
的所有 可下发可上报(rw)
功能进行设置。可下发可上报(rw)
的功能并进行设置。useDevice
获取全部 功能点 dp
import { useDevice } from '@ray-js/sdm-react';
const { devInfo } = useDevice();
// 获取到全部 dp schema
const dpSchemas = devInfo.schema;
功能点 dp
的类型进行展示不同 UI 及交互弹窗。