0.0.9 • Published 2 years ago

@ray-js/tuya-dp-kit v0.0.9

Weekly downloads
-
License
MIT
Repository
-
Last release
2 years ago

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

  1. 为什么初始的 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';

非常简单,开始使用吧!

0.0.9

2 years ago

0.0.8

2 years ago

0.0.7

2 years ago

0.0.6

2 years ago

0.0.5-beta-6

2 years ago

0.0.5-beta-5

2 years ago

0.0.5-beta-4

2 years ago

0.0.5-beta-3

2 years ago

0.0.5-beta-2

2 years ago

0.0.5-beta-1

2 years ago

0.0.5

2 years ago

0.0.4

2 years ago

0.0.4-beta-3

2 years ago

0.0.4-beta-2

2 years ago

0.0.4-beta-1

2 years ago

0.0.3-beta-2

2 years ago

0.0.3-beta-1

2 years ago

0.0.2-beta-2

2 years ago

0.0.2-beta-1

2 years ago

0.0.1-beta-1

2 years ago