---
title: 复杂协议结构化
summary: 将 command_trans DP 中的高级功能拆解为结构化数据，提供虚拟墙、禁区、机器语音、历史地图、房间分隔、定时任务等 Hook 方法。
---

# 复杂协议结构化

> 背景： 在目前扫地机的对外方案中，一些特有的高级功能是通过DP15：command_trans进行面板与设备端通信的。在通信时，需要按照涂鸦扫地机对外协议文档约定的格式进行组装、解析，理解成本及开发成本都比较高。为了帮助开发者快速的构建一款扫地机应用，我们将此DP中的功能拆解成结构化数据进行两端通信。


## 如何接入
### 设备端
设备端SDK版本要求：[tuyaos_robot_rvc_sdk>=1.0.0 版本才可使用](https://developer.tuya.com/cn/docs/iot-device-dev/robot_version_release?id=Kdsoylvhv0oqg)

### 面板端
在 @ray-js/robot-data-stream 依赖包中，针对特定的高级功能提供了相应的请求及设置方法，同时此依赖包也注册了一个事件监听器 **StreamDataNotificationCenter** ，当设备端回复了相应的指令时，面板开发者可以通过事件监听的方式收到上报的数据。

## 功能列表

### 虚拟墙
```typescript
const { requestVirtualWall, setVirtualWall } = useVirtualWall(devId);
```
虚拟墙功能提供了两个方法，分别是设置虚拟墙 **setVirtualWall** 和查询虚拟墙 **requestVirtualWall** 。

#### 设置置虚拟墙
**参数**
- `params` (对象): 包含以下属性的对象
  - points (string[]): 虚拟墙的端点坐标，参考格式['x0,y0,x1,y1','x2,y2,x3,y3']，x0 | y0：虚拟墙其中一个点的坐标，x1 | y1：虚拟墙另一个点的坐标
  - num (humber，可选): 虚拟墙个数
  - mode: (number[]，可选),虚拟墙的清扫模式，0: 全禁，1: 禁扫， 2:禁拖， 如果此功能未使用，可以忽略此参数

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。

```typescript
// Response 对象结构

type Response = {
  modes: number[]; // 虚拟墙的模式
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  num: number; // 虚拟墙的数量
  reqType: "virtualWallQry"; // 请求类型，固定为 "virtualWallQry"
  mapId: number; // 地图ID
  version: string; // 版本号
  taskId: string; // 任务ID
  points: string[]; // 虚拟墙的点数组
}
```

**例子**
```typescript
// 导入useVirtualWall
import { useVirtualWall } from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
// 初始化setVirtualWall
const { setVirtualWall } = useVirtualWall(devId);

setVirtualWall({
  points:['10,10,50,40']
}).then(data=>{
  // 表示设置成功
  console.log(data)
  //   {
  //     "reqType": "virtualWallQry",
  //     "version": "1.0.0",
  //     "num": 1,
  //     "modes": [
  //         0
  //     ],
  //     "points": [
  //         "-113, -11, -30, -26"
  //     ],
  //     "mapId": 2,
  //     "success": true,
  //     "errCode": 0,
  //     "taskId": "1738980882764"
  // }
}).catch(error=>{
  // 表示操作失败，设备返回失败或设备超时未响应导致失败，超时时间5s
  console.log(error)
})
```

**注意**

- 下发给设备的坐标点信息需要机器坐标系下的数据，通过扫地机 SDK 获取的虚拟墙坐标信息需要根据原点坐标进行转换。
- 收到设备虚拟墙信息的回复后，会抛出 `virtualWallQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。

#### 查询虚拟墙
**参数**

--

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。



```typescript
// Response 对象结构

type Response = {
  modes: number[]; // 虚拟墙的模式
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  num: number; // 虚拟墙的数量
  reqType: "virtualWallQry"; // 请求类型，固定为 "virtualWallQry"
  mapId: number; // 地图ID
  version: string; // 版本号
  taskId: string; // 任务ID
  points: string[]; // 虚拟墙的点数组
}
```
**例子**

```typescript
// 导入useVirtualWall
import { useVirtualWall,StreamDataNotificationCenter,VirtualWallEnum } from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
// 初始化setVirtualWall
const { requestVirtualWall } = useVirtualWall(devId);

requestVirtualWall();

// 监听虚拟墙设备上报信息
 StreamDataNotificationCenter.on(VirtualWallEnum.query, handleVirtualWall);

// 在这个方法中可以获取到设备上报的虚拟墙信息，可以更新项目中的redux数据
const handleVirtualWall = (data)=>{
  console.log(data)
}
```

**注意**

- 设备上报的坐标点数据是机器坐标系下的数据，传入扫地机SDK时需要将数据转换成屏幕坐标系下的数据。
- 收到设备虚拟墙信息的回复后，会抛出 `virtualWallQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。


### 禁区
```typescript
const { requestVirtualArea, setVirtualArea } = useVirtualArea(devId);
```
禁区功能提供了两个方法，分别是设置禁区**setVirtualArea**和查询禁区**requestVirtualArea**
#### 设置禁区
**参数**
- `params` (对象): 包含虚拟区域设置参数的对象，具有以下属性：
  - polygons (string[]): 多边形数组，每个元素为一个多边形的坐标字符串。
  - names (string[], 可选): 名称数组，每个元素为一个区域的名称。
  - modes (number[]): 模式数组，每个元素为一个区域的模式，0:全禁，1:禁扫，2:禁拖。
  - num (number, 可选): 虚拟区域的数量。

**返回值**

Promise<VirtualAreaResponse>: 一个 Promise 对象，表示异步操作的响应结果。


```typescript
// VirtualAreaResponse对象结构
interface VirtualAreaResponse {
  reqType: string; // 请求类型
  version: string; // 版本号
  num: number; // 虚拟区域的数量
  modes: number[]; // 模式数组，每个元素为一个区域的模式
  polygons: string[]; // 多边形数组，每个元素为一个多边形的坐标字符串
  names: string[]; // 名称数组，每个元素为一个区域的名称
  mapId: number; // 地图ID
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  taskId: string; // 任务ID
}
```
**例子**

```typescript
// 导入useVirtualArea
import { useVirtualArea } from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
const { setVirtualArea } = useVirtualArea(devId);

 setVirtualArea({
    "polygons": [
        "-165,64,-81,64,-81,19,-165,19",
        "-175,53,-92,53,-92,9,-175,9"
    ],
    "modes": [
        0,
        2
    ],
})
  .then(data => {
    console.log(data);
//    {
//     "reqType": "restrictedAreaQry",
//     "version": "1.0.0",
//     "num": 2,
//     "modes": [
//         0,
//         2
//     ],
//     "polygons": [
//         "-165, 64,-81, 64,-81, 19,-165, 19",
//         "-175, 53,-92, 53,-92, 9,-175, 9"
//     ],
//     "names": [
//         "",
//         ""
//     ],
//     "mapId": 2,
//     "success": true,
//     "errCode": 0,
//     "taskId": "1738994024502"
// }
  })
  .catch((error) => {
    console.log(error)
  });

```

**注意**

- 下发给设备的坐标点信息需要机器坐标系下的数据，通过扫地机SDK获取的虚拟区域信息需要根据原点坐标进行转换。
- 收到设备禁区信息的回复后，会抛出 `restrictedAreaQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。

#### 查询禁区
**参数**

--

**返回值**

Promise<VirtualAreaResponse>: 一个 Promise 对象，表示异步操作的响应结果。
```typescript
// VirtualAreaResponse对象结构
interface VirtualAreaResponse {
  reqType: string; // 请求类型
  version: string; // 版本号
  num: number; // 虚拟区域的数量
  modes: number[]; // 模式数组，每个元素为一个区域的模式
  polygons: string[]; // 多边形数组，每个元素为一个多边形的坐标字符串
  names: string[]; // 名称数组，每个元素为一个区域的名称
  mapId: number; // 地图ID
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  taskId: string; // 任务ID
}
```
**例子**

```typescript
// 导入useVirtualArea
import { useVirtualArea,StreamDataNotificationCenter,VirtualAreaEnum } from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
// 初始化requestVirtualArea
const { requestVirtualArea } = useVirtualArea(devId);

requestVirtualArea();

// 监听虚拟墙设备上报信息
 StreamDataNotificationCenter.on(VirtualAreaEnum.query, handleVirtualArea);

// 在这个方法中可以获取到设备上报的虚拟墙信息，可以更新项目中的redux数据
const handleVirtualArea = (data)=>{
  console.log(data)
}
```

**注意**

- 设备上报的坐标点数据是机器坐标系下的数据，传入扫地机SDK时需要将数据转换成屏幕坐标系下的数据。
- 收到设备禁区信息的回复后，会抛出`restrictedAreaQry`的事件，可以通过StreamDataNotificationCenter进行监听。

### 机器语音
```typescript
const { requestAllVoices, requestVoiceInUse,setVoice } = useVoice(devId);
```
机器语音功能提供了三个方法，分别是查询所支持的所有设备语音 **requestAllVoices** , 查询当前使用的机器语音 **requestVoiceInUse** 和设置语音 **setVoice** 。

#### 查询语音列表
**参数**

--

**返回值**

Promise<GetVoiceListResponse>: 一个 Promise 对象，表示异步操作的响应结果。

```typescript
// GetVoiceListResponse对象结构
  type GetVoiceListResponse = {
    datas: {
      auditionUrl: string // 试听链接
      desc?: string // 描述
      extendData: {
        extendId: number // 扩展ID，通过这个id与设备上报的语言包id进行对比，判断语音包是否使用中
        version: string // 版本
      }
      id: number // ID
      imgUrl: string // 图片链接
      name: string // 名称
      officialUrl: string // 官方链接
      productId: string // 产品ID
      region: string[] // 区域代码
    }[] // 语音数据数组
    pageNo: number // 页码
    totalCount: number // 数据总数
  }

```
**例子**
```typescript
import { useVoice } from '@ray-js/robot-data-stream';
const { requestAllVoices } = useVoice(devId);

requestAllVoices()
  .then(res => {
    console.log(res.data)
  })
  .finally(() => {
    setLoading(false);
  });

```
**注意**
- 此功能是需要在涂鸦IoT平台上上传语音文件后才可使用，操作方法请联系您的客户经理或提工单进行咨询。

#### 查询使用中的语音文件
**参数**

--

**返回值**

Promise<VoiceLanguageResponse>: 一个 Promise 对象，表示异步操作的响应结果。

```typescript
// VoiceLanguageResponse对象结构
interface VoiceLanguageResponse {
  reqType: string; // 请求类型
  version: string; // 版本号
  id: number; // 语音语言ID
  schedule: number; // 进度百分比
  status: number; // 状态码
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  taskId: string; // 任务ID
}
```
**例子**
```typescript
requestVoiceInUse().then(data => {
  console.log(data);
// {
//     "reqType": "voiceLanguageQry",
//     "version": "1.0.0",
//     "id": 0,
//     "schedule": 100,
//     "status": 3,
//     "success": true,
//     "errCode": 0,
//     "taskId": "1738996454610"
// }
});
```
**注意**
- 在收到设备当前使用的语音文件的回复后，会抛出 `voiceLanguageQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。

#### 设置语音
**参数**
- message (对象): 包含语音语言设置参数的对象，具有以下属性：
  - id (number): 语音语言ID。
  - url (string): 语音语言文件的URL。
  - md5 (string): 语音语言文件的MD5值。

**返回值**

Promise<VoiceLanguageResponse>: 一个 Promise 对象，表示异步操作的响应结果。


```typescript
// VoiceLanguageResponse对象结构
interface VoiceLanguageResponse {
  reqType: string; // 请求类型
  version: string; // 版本号
  id: number; // 语音语言ID
  schedule: number; // 进度百分比
  status: number; // 状态码
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  taskId: string; // 任务ID
}
```
**例子**
```typescript
import { useVoice,StreamDataNotificationCenter ,VoiceLanguageEnum} from '@ray-js/robot-data-stream';

const { setVoice } = useVoice(devId);

// 这里的数据来源是requestAllVoices方法中返回的数据
setVoice({
  id: extendData.extendId,
  url: officialUrl,
  md5: desc,
});

// 监听设备上报
StreamDataNotificationCenter.on(VoiceLanguageEnum.query, (data) => {
  console.log('收到了voiceLanguageQry====>', data);
});
```

**注意**
- 下发设备语音后，设备端会定时上报语音文件的下载进度直至下载完成，因此代码实现时建议使用事件监听的方式
- 在每次收到设备下载语音文件的回复后，会抛出 `voiceLanguageQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。

### 机器信息
```typescript
const { requestDevInfo } = useDevInfo(devId);
```
机器信息功能提供了1个方法,请求机器信息 **requestDevInfo** 。

#### 请求机器信息
**参数**

--

**返回值**

Promise<DevInfoResponse>: 一个 Promise 对象，表示异步操作的响应结果。


```typescript
// DevInfoResponse 对象结构

interface DevInfoResponse {
  reqType: string; // 请求类型
  version: string; // 版本号
  info: string; // 设备信息的 JSON 字符串
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  taskId: string; // 任务ID
}
```
**例子**
```typescript
import { useDevInfo } from '@ray-js/robot-data-stream';

const { requestDevInfo } = useDevInfo(devId);

   requestDevInfo()
      .then(data => {
        const { info } = data;
        const robotInfo = JsonUtil.parseJSON(info);
        console.log(robotInfo)
//      {
//     "WiFi_Name": "robot",
//     "RSSI": 58,
//     "IP": "**",
//     "Mac": "**",
//     "Firmware_Version": "**",
//     "Device_SN": "**",
//     "Module_UUID": "**"
// }
      })
      .catch(error => {
        console.log(error);
      });

```
**注意**
- 在收到设备机器信息回复后，会抛出 `devInfoQry` 的事件，可以通过StreamDataNotificationCenter进行监听。

### 历史地图
```typescript
const { deleteHistoryMap, changeCurrentMap,saveMap } = useHistoryMap(devId);
```
历史地图功能提供了3个方法，分别是保存地图 **saveMap**、删除历史地图 **deleteHistoryMap**、修改首页地图 **changeCurrentMap**


#### 保存地图
**参数**

--

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。


```typescript
// Response 对象结构

type Response = {
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  reqType: string; // 请求类型
  version: string; // 版本号
  taskId: string; // 任务ID
}
```
**例子**

```typescript
import { useHistoryMap,StreamDataNotificationCenter ,SaveCurrentMapEnum} from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
const { saveMap } = useHistoryMap(devId);

saveMap().then(()=>{
  console.log('保存成功')
}).catch(()=>{
  console.log('保存失败')
});

// 监听保存地图的设备上报
 StreamDataNotificationCenter.on(SaveCurrentMapEnum.query, (data)=>{
  console.log(data)
 });

```


- 在收到设备保存地图的回复后，会抛出 `SaveCurrMapRst` 的事件，可以通过 StreamDataNotificationCenter 进行监听。

#### 删除地图
**参数**

mapId (number): 地图云端ID。

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。


```typescript
// Response 对象结构

type Response = {
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  reqType: string; // 请求类型
  version: string; // 版本号
  taskId: string; // 任务ID
}
```


**例子**
```typescript
import { useHistoryMap,StreamDataNotificationCenter ,DeleteMapEnum} from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
const { deleteHistoryMap } = useHistoryMap(devId);

 deleteHistoryMap(id)
  .then((data) => {
    console.log('删除成功')
  }).catch(error=>{
    console.log(error)
  })

// 监听删除历史地图的上报
 StreamDataNotificationCenter.on(DeleteMapEnum.rst, ()=>{
  console.log('收到设备上报')
 });
```
**注意**

在收到设备保存地图的回复后，会抛出 `deleteMapRst` 的事件，可以通过 StreamDataNotificationCenter 进行监听。

#### 修改首页地图
**参数**

- mapId (number): 地图ID。
- url (string): 地图URL。


**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。

```typescript
// Response 对象结构

type Response = {
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  reqType: string; // 请求类型
  mapId: number; // 地图ID
  version: string; // 版本号
  taskId: string; // 任务ID
}
```
**例子**
```typescript
import { useHistoryMap,UseMapEnum,StreamDataNotificationCenter } from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
const { changeCurrentMap } = useHistoryMap(devId);

const mapId = 123;
const url = 'https://example.com/map.png';

changeCurrentMap(mapId, url).then(response => {
  console.log('更改成功:', response);
}).catch(error => {
  console.error('更改失败:', error);
});

 StreamDataNotificationCenter.on(UseMapEnum.query, ()=>{
  console.log('收到设备上报')
 });

```
**注意**

在收到设备保存地图的回复后，会抛出 `useMapRst` 的事件，可以通过 StreamDataNotificationCenter 进行监听。

### 房间分隔
```typescript
const {setPartDivision} = usePartDivision(devId);
```
房间分隔为一个用户操作行为，此 hooks 中仅提供了一个房间分隔操作 **setPartDivision** 的函数。
#### 房间分隔
**参数**

- points (Point[]): 分隔点数组，SDK方法抛出来的坐标直接传入即可。
- roomId (number): 房间ID，当前要分隔的房间。
- origin (Point): 地图原点坐标。

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。

```typescript
// Response 对象结构

type Response = {
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  reqType: string; // 请求类型
  version: string; // 版本号
  taskId: string; // 任务ID
}
```

**例子**

```typescript
import { usePartDivision } from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
const { setPartDivision } = usePartDivision(devId);

const points = [
  { x: 100, y: 100 },
  { x: 200, y: 200 },
];
const roomId = 1;
const origin = { x: 0, y: 0 };


setPartDivision(points, roomId, origin).then(()=>{
  console.log('保存成功')
}).catch(()=>{
  console.log('保存失败')
});

```

**注意**

- 在收到设备房间分隔的回复后，会抛出 `partDivisionRst` 的事件，可以通过 StreamDataNotificationCenter 进行监听。
- `setPartDivision` 方法传入的分割线坐标为屏幕坐标系下的数据，即扫地机SDK方法中抛出来的数据

### 分区合并
```typescript
const {setPartMerge} = usePartMerge(devId);
```
分区合并为一个用户操作行为，此 hooks 中仅提供了一个房间分隔操作 **setPartMerge** 的函数。
#### 分区合并
**参数**

- ids (number[]): 要合并的房间ID数组。

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。

```typescript
// Response 对象结构

type Response = {
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  reqType: string; // 请求类型
  version: string; // 版本号
  taskId: string; // 任务ID
}
```
**例子**
```typescript
import { usePartMerge } from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
const { setPartMerge } = usePartMerge(devId);

const ids = [1, 2, 3];

setPartMerge(ids).then(response => {
  console.log('设置成功:', response);
}).catch(error => {
  console.error('设置失败:', error);
});

```
**注意**

- 在收到设备房间合并的回复后，会抛出`partMergeRst`的事件，可以通过StreamDataNotificationCenter进行监听。

### 勿扰模式

```typescript
import { useQuiteHours } from '@ray-js/robot-data-stream';

const { setQuiteHours ,requestQuiteHours} = useQuiteHours(devId);
```
 勿扰模式功能提供了两个方法，分别是设置勿扰模式 **setQuiteHours** 和查询勿扰模式 **requestQuiteHours** 。


#### 请求勿扰模式
**参数**

--

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。

```typescript
// Response 对象结构

type Response = {
  time: string[]; // 时间段数组，每个元素为 "开始时间, 结束时间" 的字符串
  day: number; // 是否有跨天，1 表示有，0 表示无。
  active: number; // 是否激活，0 表示未激活，1 表示激活
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  reqType: string; // 请求类型
  mapId: number; // 地图ID
  version: string; // 版本号
  taskId: string; // 任务ID
}
```

**例子**

```typescript
// 导入useVirtualWall
import { useQuiteHours } from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
// requestQuiteHours
const { requestQuiteHours } = useVirtualWall(devId);

requestQuiteHours().then(data => {
  console.log('勿扰模式数据:', data);
  //  {
  //   "reqType": "quietHoursQry",
  //   "time": ["9,15", "0,18"],
  //   "version": "1.0.0",
  //   "day": 1,
  //   "taskId": "1733126622485"，
  //   "mapId":111
  // }
}).catch(error => {
  console.error('请求失败:', error);
});
```


#### 设置勿扰模式

**参数**

- `params` (对象): 包含勿扰模式设置参数的对象，具有以下属性：
  - `startTime` (对象): 开始时间，包含以下属性：
    - `hour` (number): 小时，范围为 0-23。
    - `minute` (number): 分钟，范围为 0-59。
  - `endTime` (对象): 结束时间，包含以下属性：
    - `hour` (number): 小时，范围为 0-23。
    - `minute` (number): 分钟，范围为 0-59。
  - `active` (number): 勿扰模式开关，1 表示开启，0 表示关闭。
  - `day` (number): 是否有跨天，1 表示有，0 表示无。
  - `version` (string, 可选): 协议版本。

**返回值**

返回值`Promise`: Promise 对象，用于处理异步操作的结果。

```typescript
{ 
  reqType: string;  // 请求类型
  version: string;// 版本号
  active: number;// 是否激活，0 表示未激活，1 表示激活
  time: string[];// 时间段数组，每个元素为 "开始时间, 结束时间" 的字符
  day: number;// 是否有跨天，1 表示有，0 表示无。
  success: boolean; // 请求是否成功
  errCode: number;// 错误代码，0 表示无错误
  taskId: string; // 任务ID
}
```

**例子**

```typescript
import { Switch } from '@ray-js/smart-ui';
import { useQuiteHours } from '@ray-js/robot-data-stream';

// 设备ID
const { devId } = useDevice(device => device.devInfo);
const { setQuiteHours } = useQuiteHours(devId);


  setQuiteHours({
    startTime:{
      hour:22,
      minute:0
    },
    endTime:{
      hour:8,
      minute:0
    },
    active: value,
    day: 1,
  })
    .then(data => {
     console.log('修改成功')
    })
    .catch(() => {
     console.log('修改失败')
    });


```


### 重置地图

```typescript
const {setResetMap} = useResetMap(devId);
```

#### 重置地图
**参数**

--

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。

```typescript
// Response 对象结构

type Response = {
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  reqType: string; // 请求类型
  version: string; // 版本号
  taskId: string; // 任务ID
}
```
**例子**
```typescript
import { useResetMap } from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
const { setResetMap } = useResetMap(devId);


setResetMap().then(response => {
  console.log('重置地图成功', response);
}).catch(error => {
  console.error('重置地图失败:', error);
});

```


### 房间属性
```
const { requestRoomProperty, setRoomProperty } = useRoomProperty(devId);
```
房间属性功能提供了两个方法，分别是设置房间属性 **setRoomProperty** 和查询房间属性 **requestRoomProperty** 。

#### 设置房间属性
**参数**

- message (对象): 包含房间属性设置参数的对象，具有以下属性：
  - suctions (string[], 可选): 吸力数组。
  - cisterns (string[], 可选): 水箱数组。
  - cleanCounts (number[], 可选): 清扫次数数组。
  - yMops (number[], 可选): 拖布数组。
  - sweepMopModes (string[], 可选): 扫拖模式数组。
  - names (string[], 可选): 名称数组。
  - ids (number[]): 房间ID数组。

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。
```typescript
// Response 对象结构
type Response = {
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  reqType: string; // 请求类型
  version: string; // 版本号
  taskId: string; // 任务ID
  num:number; //房间数量
  mapId：number;//地图id
    // 吸力， closed - 关闭 gentle - 安静 normal - 正常 strong - 强劲 max - 超强 ，默认值为''
  suctions?: string[];
  // 拖地水量 "closed"- 关闭,"low"-低,"middle"-中,"high"-高,默认值为''
  cisterns?: string[];
  // 清扫次数 默认值1
  cleanCounts?: number[];
  // 拖地模式 1:开启Y型拖地 0:关闭Y型拖地  -1 未设置 默认值-1
  yMops?: number[];
  // 扫拖模式 "only_sweep":仅扫,"only_mop"：仅拖,"both_work"：扫拖同时,"clean_before_mop"：先扫后拖，默认值为'only_sweep'
  sweepMopModes?: string[];
  // 房间地板类型，默认值-1
  floorTypes?: number[];
  // 房间名称，默认是空字符串
  names?: string[];
  // 房间id集合
  ids?: number[];
  // 房间顺序
  orders?: number[];
}
```
**例子**
```typescript
import { useRoomProperty } from '@ray-js/robot-data-stream';
const { devId } = useDevice(device => device.devInfo);
const { setRoomProperty } = usePartMerge(devId);

const roomPropertyData = {
  suctions: ['low', 'gentle', 'max'],
  cisterns: ['closed', 'middle', 'high'],
  cleanCounts: [1, 2, 1],
  yMops: [0, 1, -1],
  sweepMopModes: ['only_sweep', 'sweep_and_mop', 'only_mop'],
  names: ['Living Room', 'Bedroom', 'Kitchen'],
  ids: [1, 2, 3],
  floorTypes:[-1,-1,-1]
  orders:[1,2,3]
};

setRoomProperty(roomPropertyData).then(response => {
  console.log('设置成功:', response);
}).catch(error => {
  console.error('设置失败:', error);
});

```
**注意**

- 设置房间属性时需要注意要将所有的房间属性都需要传入，比如现在在修改房间地板，在下发时也需要将房间名称等数据同时下发给设备。
- suctions，cisterns 等字段的顺序需要保持与ids的顺序一致，比如ids第1个数据是卧室，那 suctions 第1个元素也需要是卧室的吸力。
#### 请求房间属性
**方法名**

requestRoomProperty

**参数**

--

**返回值**

参考 `setRoomProperty` 。

**例子**

```typescript
import { useRoomProperty } from '@ray-js/robot-data-stream';
const { devId } = useDevice(device => device.devInfo);
const { requestRoomProperty } = usePartMerge(devId);

requestRoomProperty().then(response => {
  console.log('房间属性数据:', response);
}).catch(error => {
  console.error('请求失败:', error);
});

```


### 定时任务
```
const { requestSchedule, setSchedule } = useSchedule(devId);
```
定时任务功能提供了两个方法，分别是设置定时 **setSchedule** 和查询定时 **requestSchedule** 。

#### 设置定时
**参数**
- message (对象): 包含定时任务设置参数的对象，具有以下属性：
  - list (Array<ScheduleItem>): 定时任务列表。
  - num (number): 定时任务数量。

```typescript
type ScheduleItem = {
   // 吸力， closed - 关闭 gentle - 安静 normal - 正常 strong - 强劲 max - 超强 ，默认值为''
  suctions?: string[];
   // 拖地水量 "closed"- 关闭,"low"-低,"middle"-中,"high"-高,默认值为''
  cisterns?: string[];
  // 拖地模式 1:开启Y型拖地 0:关闭Y型拖地  -1 未设置 默认值-1
  yMops?: number[];
 // 扫拖模式 "only_sweep":仅扫,"only_mop"：仅拖,"both_work"：扫拖同时,"clean_before_mop"：先扫后拖，默认值为'only_sweep'
  sweepMopModes?: string[];
    // 房间id集合，如果ids 为空数组，则表示全屋执行
  ids?: number[];
  // 定时是否有效，0：定时关闭 1:定时开启
  active: number; 
  // 周循环，周一到周日
  cycle: number[]; 
   // 执行时间, [小时, 分钟]
  time: number[];
};
```

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。
```typescript
// Response 对象结构,ScheduleItem 结构与入参结构一致
type Response ={
  reqType: string; // 请求类型
  version: string; // 版本号
  success: boolean; // 请求是否成功
  errCode: number; // 错误代码，0 表示无错误
  taskId: string; // 任务ID
  list: Array<ScheduleItem>;
  num: number;
};

```

**例子**
```typescript
import { useSchedule } from '@ray-js/robot-data-stream';
const { devId } = useDevice(device => device.devInfo);
const {  setSchedule } = useSchedule(devId);


const scheduleData = {
  list: [
    {
      // 定时开启
      active: 1,
      // 仅执行一次
      cycle:[0,0,0,0,0,0,0],
      // 清扫时间8:00
      time: [8, 0],
      // 吸力正常
      suctions: ['normal'],
      // 水量关闭
      cisterns: ['closed'],
      // 仅清扫一次
      cleanCounts: [1],
      // y字型拖地关闭
      yMops: [0],
      // 禁扫模式
      sweepMopModes: ['only_sweep'],
      // 全屋清扫
      ids: [],
    },
  ],
  num: 1,
};

setSchedule(scheduleData).then(response => {
  console.log('设置成功:', response);
}).catch(error => {
  console.error('设置失败:', error);
});
```

**注意**

-  定时数据需要全量下发，比如现在已经添加了1条定时，在第二条定时添加时，下发的列表数据中需要包含第一条定时的数据

#### 查询定时
**参数**

--

**返回值**

参考 setSchedule 方法的返回参数。


**例子**

```typescript
import { useSchedule } from '@ray-js/robot-data-stream';
const { devId } = useDevice(device => device.devInfo);
const { requestRoomProperty } = useSchedule(devId);

requestSchedule().then(response => {
  console.log('定时数据:', response);
}).catch(error => {
  console.error('请求失败:', error);
});

```

### 选区清扫
```
const { requestSelectRoomClean, setRoomClean } = useSelectRoomClean(devId);
```
选区清扫功能提供了两个方法，分别是设置选区清扫 **setSpotClean** 和查询选区清扫 **requestSpotClean** 。

#### 设置选区清扫
**参数**
- message (对象): 包含选区清扫设置参数的对象，具有以下属性：
  - ids (number[]): 房间ID数组。
  - suctions (string[], 可选): 吸力数组。
  - cisterns (string[], 可选): 水箱数组。
  - cleanCounts (number[], 可选): 清扫次数数组。
  - yMops (number[], 可选): 拖布数组。
  - sweepMopModes (string[], 可选): 扫拖模式数组。

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果

```typescript
// Response 对象结构,ScheduleItem 结构与入参结构一致
type Response ={
   reqType: string; // 请求类型
    version: string; // 版本号
    success: boolean; // 请求是否成功
    errCode: number; // 错误代码，0 表示无错误
    taskId: string; // 任务ID
    ids:string[];  // 房间id
    suctions: string[];//吸力
    cisterns:string[]; // 拖地水量
    cleanCounts:number[];//清扫次数
    yMops: number[];//拖地模式 
    sweepMopModes: string[];  //扫拖模式 
};

```

**例子**

```typescript
const roomCleanData = {
  ids: [1, 2, 3],
  suctions: ['strong', 'strong', 'high'],
  cisterns: ['low', 'middle', 'high'],
  cleanCounts: [1, 2, 1],
  yMops: [0, 1, 0],
  sweepMopModes: ['only_sweep', 'clean_before_mop', 'both_work'],
};

setRoomClean(roomCleanData).then(() => {
  console.log('设置成功');
}).catch(error => {
  console.error('设置失败:', error);
});
```

**注意**

- 在收到设备选区清扫的回复后，会抛出 `roomCleanQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。


#### 查询选区清扫
**参数**

--

**返回值**

参考 `setRoomClean` 。

**例子**

```typescript
import { useSelectRoomClean } from '@ray-js/robot-data-stream';
const { devId } = useDevice(device => device.devInfo);
const { requestSelectRoomClean } = useSelectRoomClean(devId);

requestSelectRoomClean().then(response => {
  console.log('清扫数据:', response);
}).catch(error => {
  console.error('请求失败:', error);
});

```

**注意**

- 在收到设备选区清扫的回复后，会抛出 `roomCleanQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。



### 划区清扫

```
const { requestZoneClean, setZoneClean } = useZoneClean(devId);
```
划区清扫功能提供了两个方法，分别是设置划区清扫 **setZoneClean** 和查询划区清扫 **requestZoneClean** 。

#### 设置划区清扫
**参数**
- message (对象): 包含定点清扫设置参数的对象，具有以下属性：
  - polygons (string[]): 多边形数组，每个元素为一个多边形的坐标字符串。
  - suctions (string[], 可选): 吸力数组。
  - cisterns (string[], 可选): 水箱数组。
  - cleanCounts (number[], 可选): 清扫次数数组。
  - yMops (number[], 可选): 拖布数组。
  - sweepMopModes (string[], 可选): 扫拖模式数组。
  - names (string[], 可选): 名称数组。

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。

```typescript
// Response 对象结构
type Response ={
   reqType: string; // 请求类型
    version: string; // 版本号
    success: boolean; // 请求是否成功
    errCode: number; // 错误代码，0 表示无错误
    taskId: string; // 任务ID
    polygons:string[];  // 多边形数组，每个元素为一个多边形的坐标字符串。
    suctions: string[];//吸力
    cisterns:string[]; // 拖地水量
    cleanCounts:number[];//清扫次数
    yMops: number[];//拖地模式 
    sweepMopModes: string[];  //扫拖模式 
    names?:string[]; //名称数组。
};

```

**例子**

```typescript
const zoneCleanData = {
  polygons: ['-165,64,-81,64,-81,19,-165,19', '-175,53,-92,53,-92,9,-175,9'],
  suctions: ['gentle', 'normal'],
  cisterns: ['closed', 'middle'],
  cleanCounts: [1, 2],
  yMops: [0, 1],
  sweepMopModes: ['only_sweep', 'both_work'],
  names: ['区域1', '区域2'],
};

setZoneClean(spotCleanData).then(response => {
  console.log('设置成功:', response);
}).catch(error => {
  console.error('设置失败:', error);
});
```
**注意**

- 在收到设备划区清扫的回复后，会抛出 `zoneCleanQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。
#### 查询划区清扫
**参数**

--

**返回值**

参考 `setZoneClean` 返回值。

**注意**

- 在收到设备划区清扫的回复后，会抛出 `zoneCleanQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。

### 定点清扫
```typescript
const { requestSpotClean, setSpotClean } = useSpotClean(devId);
```
定点清扫功能提供了两个方法，分别是设置定点清扫 **setSpotClean** 和查询定点清扫 **requestSpotClean** .

#### 设置定点清扫
**参数**

- message (对象): 包含定点清扫设置参数的对象，具有以下属性：
  - polygons (string[]): 多边形数组，每个元素为一个多边形的坐标字符串。
  - suctions (string[], 可选): 吸力数组。
  - cisterns (string[], 可选): 水箱数组。
  - cleanCounts (number[], 可选): 清扫次数数组。
  - yMops (number[], 可选): 拖布数组。
  - sweepMopModes (string[], 可选): 扫拖模式数组。
  - names (string[], 可选): 名称数组。

**返回值**

Promise<Response>: 一个 Promise 对象，表示异步操作的响应结果。

```typescript
// Response 对象结构
type Response ={
   reqType: string; // 请求类型
    version: string; // 版本号
    success: boolean; // 请求是否成功
    errCode: number; // 错误代码，0 表示无错误
    taskId: string; // 任务ID
    polygons:string[];  // 多边形数组，每个元素为一个多边形的坐标字符串。
    suctions: string[];//吸力
    cisterns:string[]; // 拖地水量
    cleanCounts:number[];//清扫次数
    yMops: number[];//拖地模式 
    sweepMopModes: string[];  //扫拖模式 
    names?:string[]; //名称数组。
};

```

**例子**

```typescript
import { useSpotClean } from '@ray-js/robot-data-stream';

const { devId } = useDevice(device => device.devInfo);
const { setSpotClean } = useSpotClean(devId);

const params ={
  "yMops":[-1],
  "names":[""],
  "polygons":["13,30"],
  "num":1,
  "suctions":["max"],
  "cisterns":["max"],
  "sweepMopModes":["both_work"]
}

setSpotClean(params).then((data)=>{
  console.log('设置定点清扫',data)
}).catch(err=>{
  console.log(err)
})

```
**注意**

- 在收到设备定点清扫的回复后，会抛出 `spotCleanQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。


#### 查询定点清扫
**参数**

--

**返回值**

参考 `setSpotClean` 返回值.

**例子**

```typescript
import { useSpotClean } from '@ray-js/robot-data-stream';
const { devId } = useDevice(device => device.devInfo);
const { requestSpotClean } = useSpotClean(devId);

requestSpotClean().then(response => {
  console.log('定点清扫数据:', response);
}).catch(error => {
  console.error('请求失败:', error);
});

```

**注意**

- 在收到设备定点清扫的回复后，会抛出 `spotCleanQry` 的事件，可以通过 StreamDataNotificationCenter 进行监听。
