@ray-js/tuya-dp-kit
v0.0.9
Published
Tuya Dp Kit from dp send and response
Downloads
36
Readme
Tuya Dp Kit
轻量的面板 dp 处理工具库,加入 Redux 数据流,内置 tuya-dp-transform。
支持 RN / Ray 下使用。
安装
yarn add @ray-js/tuya-dp-kit
用法
createDpKitMiddleware
配置化的创建 dp 处理中间件的函数
const createDpKitMiddleware: <D extends Record<string, any>>({
rawDpMap?: Partial<Record<keyof D, DpMap>>;
sendDpOption?: SendDpOption<D>;
} = {}) => Middleware;
参数
putDeviceData
(必填)
实际的下发方法,若用于 RN 面板开发,通常为TYSdk.device.putDeviceData
rawDpMap
(可选)
指定应用里的协议型 dp 的解析方式(参考tuya-dp-transform),将自动解析&反解析这类 dp,无需再在业务代码里进行处理。
const dpKitMiddleware: Middleware = createDpKitMiddleware<DpState>({
rawDpMap: {
colour_data: [
{
name: 'hue',
bytes: 2,
extension: {
min: 0,
max: 360,
},
},
{
name: 'saturation',
bytes: 2,
extension: {
min: 0,
max: 1000,
},
},
{
name: 'brightness',
bytes: 2,
extension: {
min: 0,
max: 1000,
},
},
],
custom_raw_dp: {
parser: (dpValue) => {
// 自定义解析
},
formatter: (dpValue) => {
// 自定义格式化
}
}
},
});
/**
* action(RESPONSE_UPDATE_DP): colour_data => 000003e803e8
* state.dpState.colour_data => { hue: 0, saturation: 1000, brightness: 1000 }
*/
/**
* action(CHANGE_DP): colour_data => { hue: 0, saturation: 1000, brightness: 1000 }
* 下发: colour_data => 000003e803e8
* /
sendDpOption
(可选)
下发 dp 的选项。若配置在createDpKitMiddleware
中,将影响后续所有的下发指令。
type SendDpOption<D = any> = {
/**
* 立即触发state更新
*/
immediate?: boolean;
/**
* 多个dp是否按对象里的顺序下发(可以确保固件收到的顺序)
*/
ordered?: boolean;
/**
* 重复值不下发
*
* 与当前`dpState`进行比较,重复值检出不下发
*/
checkRepeat?: boolean;
/**
* 过滤过时的下发引起的上报
*
* 比如:Slider通常同时受控于用户滑动、点击以及dp上报值,这就可能造成:短时间内连续滑动、点击触发多次下发,后续接收到多次上报后Slider会出现抖动。
* 建议和`immediate`一起使用
*/
filterExpired?: boolean;
/**
* 延迟下发
*/
delay?: number;
/**
* 下发节流
*/
throttle?: number;
/**
* 下发防抖
*/
debounce?: number;
/**
* dp解析与反解析
*/
rawDpMap?: Partial<Record<keyof D, DpMap>>;
};
例如,如果期望应用内的下发都具有 600ms 的节流,你可以:
const dpKitMiddleware: Middleware = createDpKitMiddleware<DpState>({
sendDpOption: {
throttle: 600,
},
});
或者,如果期望state.dpState
不再等到 dp 上报后才更新,你可以:
const dpKitMiddleware: Middleware = createDpKitMiddleware<DpState>({
sendDpOption: {
immediate: true,
},
});
onBeforeSendDp
/ onAfterSendDp
(可选)
下发 dp 前/后的钩子(在 putDeviceData 之前/之后),建议传入 RootState 以确保获得正确的 type
const dpKitMiddleware: Middleware = createDpKitMiddleware<DpState, RootState>({
// dpState @ 当次下发的dp
onBeforeSendDp: (dpState, { getState, dispatch }) => {},
onAfterSendDp: (dpState, { getState, dispatch }) => {},
});
onResponseDp
监听到 dp 上报后的钩子(在 store 状态变化之前),建议传入 RootState 以确保获得正确的 type
const dpKitMiddleware: Middleware = createDpKitMiddleware<DpState, RootState>({
// dpState @ 当次上报的dp
onResponseDp: (dpState, { getState, dispatch }) => {},
});
onInitializeDp
监听到 dp 初始化的钩子(由 DevInfoChange 引起,在 store 状态变化之前),建议传入 RootState 以确保获得正确的 type
const dpKitMiddleware: Middleware = createDpKitMiddleware<DpState, RootState>({
// dpState @ 初始化的dp
onInitialize: (dpState, { getState, dispatch }) => {},
});
updateDpCreator
updateDpCreator
创建一个用于下发 dp 的 actionCreator。若需要 tuya-dp-kit
提供的能力,请确保应用内的下发统一使用 dispatch(updateDp({...})
的方式,不再使用原生的 TYSdk.device.putDeviceData({...})
。
你可以通过updateDp({}, options)
使用一些配置式的选项来增强你这一次的下发功能。
最初,你需要调用updateDpCreator
来创建一个 updateDp 函数,例如:
export const updateDp = updateDpCreator<Partial<DpState>>();
后续你就可以通过这个函数来下发你的 dp 并开启一些你需要的特性了。
例如,如果期望针对开关有 1s 的节流,你可以:
dispatch(updateDp({ switch: true }, { throttle: 1000 }));
或者,如果期望亮度(很可能是一个 Slider 组件)具备[过滤过时下发引起的上报]的能力,你可以:
dispatch(updateDp({ brightValue: 60 }, { filterExpired: true }));
如何在现有项目中使用?
家电 RN 模板已支持 tuya-dp-kit,欢迎体验使用 👏。
如果你需要在公版 RN 面板模板内使用 tuya-dp-kit
,需要进行一点点的改造。
原有的updateDp
下发 dp 的逻辑是借助redux-observable
(rx
的一个中间件库)来实现的,但仅仅想要实现“updateDp
下发 dp” 完全不需要用到rx
,大材小用且让我们的工程变得臃肿(ios bundle 体积增加了约 190kb)。
因此,引入tuya-dp-kit
后,你可以把工程内redux-observable
的逻辑全部移除。
如果不太清楚相关的逻辑在哪,你可以在src/models
下搜索epic
,删掉所有相关代码即可。
同时,相关的库也可以一并移除
yarn remove redux-observable rxjs rxjs-compat
这样以后,就可以使用了tuya-dp-kit
了,只需要:
- 通过
createDpKitMiddleware
创建一个中间件并加入已有的中间件
// src/models/configureStore.ts
const dpKitMiddleware = createDpKitMiddleware<DpState>({
putDeviceData: someSendDpFunction /* 下发dp的方法 */,
});
const middlewares = isDebuggingInChrome
? [logger, dpKitMiddleware]
: [dpKitMiddleware];
- 创建一个
updateDp
函数
// src/models/modules/common.ts
export const updateDp = updateDpCreator<Partial<DpState>>();
FAQ
- 为什么初始的 raw dp 转换不起作用?
注意一下,初始化的 devInfoChange 的 action type 是否为DEV_INFO_CHANGE
,部分模板里可能为_DEVINFOCHANGE_
,需要纠正
附上目前起作用的几个 action
export const CHANGE_DP = 'CHANGE_DP';
export const RESPONSE_UPDATE_DP = 'RESPONSE_UPDATE_DP';
export const DEV_INFO_CHANGE = 'DEV_INFO_CHANGE';
非常简单,开始使用吧!