SDM(Smart Device Model) 开发,关于 SDM 相关可以 查看 SDM 文档。SmartUI组件库 ,关于 SmartUI 相关可以 查看 SmartUI 文档。详见 面板小程序 > 搭建环境。
产品名称:惯导扫地机器人
由于产品定义了面板和设备所拥有的功能点,所以在开发一个智能设备面板之前,我们首先需要创建一个惯导扫地机器人产品,定义产品有哪些功能点,然后再在面板中一一实现这些功能点。
首先,注册登录 涂鸦开发者平台,并在平台创建产品:


🎉 完成以上步骤后,一个名为 Robot 的扫地机器人产品创建完成。
面板小程序的开发在 小程序开发者 平台上进行操作,首先请前往 小程序开发者平台 完成平台的注册登录。
详细操作步骤可以参考 创建面板小程序。
打开 IDE 创建一个基于 扫地机小程序模板 的面板小程序项目,需要在 Tuya MiniApp IDE 上操作。
详细操作步骤可以参考 初始化项目工程。

完成以上步骤后,一个面板小程序的开发模板初始化完成。以下为工程目录的介绍:
├── src
│  	├── components
│  	│   ├── CoverageMap // 涂抹型地图组件
│  	│   ├── GridMap // 栅格型地图组件
│  	│   ├── IconFont // IconFont 组件
│  	│   ├── Loading // Loading 组件
│  	├── constant
│  	│   ├── index.ts // 存放所有的常量配置
│  	├── devices // 设备模型
│  	├── hooks // hooks
│  	├── i18n // 多语言
│  	├── pages
│   │   ├── home // 首页
│   │   ├── manual // 手动控制页面
│   │   ├── map // 地图页面
│   │   ├── more // 设置页面
│   │   ├── record // 清扫记录页面
│  	├── redux // redux
│   ├── res // 图片资源 & svg 相关
│   ├── styles // 全局样式
│   ├── utils
│   │   ├── index.ts // 业务常用工具方法
│   ├── app.config.ts
│   ├── app.less
│   ├── app.tsx
│   ├── composeLayout.tsx
│   ├── global.config.ts
│   ├── mixins.less // less mixins
│   ├── routes.config.ts // 配置路由
│   ├── variables.less // less variables
├── typings // 全局类型定义
实时地图数据的获取包含两个部分
ty.getGyroLatestCleanMap获取存放在云端的最新的清扫地图的数据并将其展示src/hooks/useMapData.ts小程序目前支持 2 种样式的地图组件:

可以从@ray-js/gyro-map-component引入
import React, { FC, useEffect, useState } from "react";
import { MapApiFuncGridMap, parseGridMapData } from "@ray-js/gyro-map-sdk";
import { useMapData } from "@/hooks/useMapData";
import { getSystemInfoSync } from "ray";
import { GridMapComponent } from "@ray-js/gyro-map-component";
type Props = {
  subRecordId?: string;
  onInitialized?: () => void;
};
const GridMap: FC<Props> = ({ subRecordId, onInitialized }) => {
  // useMapData封装了获取实时地图或清扫地图数据的逻辑
  const { mapData, mapConfig } = useMapData(subRecordId);
  const [mapApiFuncs, setMapApiFuncs] = useState<MapApiFuncGridMap | null>(
    null
  );
  useEffect(() => {
    if (mapData && mapApiFuncs) {
      // parseGridMapData负责将原始地图数据转换为栅格型地图组件需要的格式
      const gridMapData = parseGridMapData([mapData], mapConfig, false);
      const {
        mapData: convertedMapData,
        pathData: convertedPathData,
        pilePosition,
      } = gridMapData;
      mapApiFuncs.drawMap(convertedMapData);
      convertedPathData.length > 0 &&
        mapApiFuncs.drawCleanPath(convertedPathData);
      pilePosition &&
        convertedMapData.data?.length > 1 &&
        mapApiFuncs.drawChargingStation(pilePosition);
    }
  }, [mapData, mapApiFuncs]);
  return (
    <GridMapComponent
      config={{
        containerTop: "120px",
        containerHeight: `${getSystemInfoSync().screenHeight - 120}px`,
        showPath: false,
      }}
      onMapReady={(funcs) => {
        // onMapReady会将该地图组件可用的API导出,这个时刻起你可以自由调用这里的API来绘制地图
        setMapApiFuncs(funcs);
        onInitialized && onInitialized();
      }}
    />
  );
};
export default GridMap;

可以从@ray-js/gyro-map-component引入
import React, { FC, useEffect, useState } from "react";
import { MapApiFuncCoverageMap, parseMapData } from "@ray-js/gyro-map-sdk";
import { useMapData } from "@/hooks/useMapData";
import { getSystemInfoSync } from "ray";
import { CoverageMapComponent } from "@ray-js/gyro-map-component";
type Props = {
  subRecordId?: string;
  onInitialized?: () => void;
};
const CoverageMap: FC<Props> = ({ subRecordId, onInitialized }) => {
  // useMapData封装了获取实时地图或清扫地图数据的逻辑
  const { mapData, mapConfig } = useMapData(subRecordId);
  const [mapApiFuncs, setMapApiFuncs] = useState<MapApiFuncCoverageMap | null>(
    null
  );
  useEffect(() => {
    if (mapData && mapApiFuncs) {
      // parseMapData负责将原始地图数据转换为涂抹型地图组件需要的格式
      const { pointsData, currentPos } = parseMapData([mapData], mapConfig);
      mapApiFuncs.drawMap && mapApiFuncs.drawMap(pointsData);
      mapApiFuncs.drawRobot && currentPos && mapApiFuncs.drawRobot(currentPos);
    }
  }, [mapData, mapApiFuncs]);
  return (
    <CoverageMapComponent
      config={{
        containerTop: "120px",
        containerHeight: `${getSystemInfoSync().screenHeight - 120}px`,
        borderWidth: 0.5,
      }}
      onMapReady={(funcs) => {
        // onMapReady会将该地图组件可用的API导出,这个时刻起你可以自由调用这里的API来绘制地图
        setMapApiFuncs(funcs);
        onInitialized && onInitialized();
      }}
    />
  );
};
export default CoverageMap;

清扫记录相关的 API 已经封装在src/api/request.ts,包含:
请注意对列表数据的处理,这里包含了一些复杂的数据解析

清扫记录详情实际上复用了地图页面,只是路由传入了记录相关的参数,地图页面在检测到这些参数传入后将走入获取清扫记录详情数据的逻辑 (可参考src/hooks/useMapData.ts)。

手动控制是一般的 DP 下发功能,使用 DP direction_control。
模板已经封装了简易的手动控制组件及页面,请参考 src/pages/manual 页面。