# Complex Protocol Structuring

> Background: In the current robot vacuum cleaner solution, some specific advanced functions communicate between the panel and the device through DP15: command_trans. During communication, it is necessary to assemble and parse according to the format agreed in the Tuya robot vacuum cleaner protocol document, which has high understanding and development costs. To help developers quickly build a robot vacuum cleaner application, we decompose the functions in this DP into structured data for communication between the two ends.

## How to Access
### Device Side
Device SDK version requirement: [tuyaos_robot_rvc_sdk>=1.0.0 version is required](https://developer.tuya.com/en/docs/iot-device-dev/robot_version_release?id=Kdsoylvhv0oqg)

### Panel Side
In the @ray-js/robot-data-stream dependency package, corresponding request and setting methods are provided for specific advanced functions. At the same time, this dependency package also registers an event listener **StreamDataNotificationCenter**. When the device side responds to the corresponding command, the panel developer can receive the reported data through event listening.

## Function List

### Virtual Wall
```typescript
const { requestVirtualWall, setVirtualWall } = useVirtualWall(devId);
```
The virtual wall function provides two methods: setting the virtual wall **setVirtualWall** and querying the virtual wall **requestVirtualWall**

#### Set Virtual Wall
**Parameters**
- `params` (object): An object containing the following properties
  - points (string[]): The endpoint coordinates of the virtual wall, reference format ['x0,y0,x1,y1','x2,y2,x3,y3'], x0 | y0: one point of the virtual wall, x1 | y1: another point of the virtual wall
  - num (number, optional): Number of virtual walls
  - mode: (number[], optional), cleaning mode of the virtual wall, 0: all forbidden, 1: forbidden to sweep, 2: forbidden to mop, if this function is not used, this parameter can be ignored

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure

type Response = {
  modes: number[]; // Modes of the virtual wall
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  num: number; // Number of virtual walls
  reqType: "virtualWallQry"; // Request type, fixed as "virtualWallQry"
  mapId: number; // Map ID
  version: string; // Version number
  taskId: string; // Task ID
  points: string[]; // Array of points of the virtual wall
}
```

**Example**
```typescript
// Import useVirtualWall
import { useVirtualWall } from '@ray-js/robot-data-stream';

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

setVirtualWall({
  points:['10,10,50,40']
}).then(data=>{
  // Indicates successful setting
  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=>{
  // Indicates operation failure, device returns failure or device timeout causes failure, timeout is 5s
  console.log(error)
})
```

**Note**

- The coordinate point information sent to the device needs to be data in the machine coordinate system. The virtual wall coordinate information obtained through the robot vacuum cleaner SDK needs to be converted according to the origin coordinates.
- After receiving the reply of the device virtual wall information, the `virtualWallQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

#### Query Virtual Wall
**Parameters**

--

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure

type Response = {
  modes: number[]; // Modes of the virtual wall
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  num: number; // Number of virtual walls
  reqType: "virtualWallQry"; // Request type, fixed as "virtualWallQry"
  mapId: number; // Map ID
  version: string; // Version number
  taskId: string; // Task ID
  points: string[]; // Array of points of the virtual wall
}
```
**Example**

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

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

requestVirtualWall();

// Listen for virtual wall device report information
 StreamDataNotificationCenter.on(VirtualWallEnum.query, handleVirtualWall);

// In this method, you can get the virtual wall information reported by the device and update the redux data in the project
const handleVirtualWall = (data)=>{
  console.log(data)
}
```

**Note**

- The coordinate point data reported by the device is data in the machine coordinate system. When passed into the robot vacuum cleaner SDK, the data needs to be converted into the screen coordinate system.
- After receiving the reply of the device virtual wall information, the `virtualWallQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

### Restricted Area
```typescript
const { requestVirtualArea, setVirtualArea } = useVirtualArea(devId);
```
The restricted area function provides two methods: setting the restricted area **setVirtualArea** and querying the restricted area **requestVirtualArea**
#### Set Restricted Area
**Parameters**
- `params` (object): An object containing the parameters for setting the virtual area, with the following properties:
  - polygons (string[]): Array of polygons, each element is a coordinate string of a polygon.
  - names (string[], optional): Array of names, each element is the name of an area.
  - modes (number[]): Array of modes, each element is the mode of an area, 0: all forbidden, 1: forbidden to sweep, 2: forbidden to mop.
  - num (number, optional): Number of virtual areas.

**Return Value**

Promise<VirtualAreaResponse>: A Promise object representing the response result of the asynchronous operation.

```typescript
// VirtualAreaResponse object structure
interface VirtualAreaResponse {
  reqType: string; // Request type
  version: string; // Version number
  num: number; // Number of virtual areas
  modes: number[]; // Array of modes, each element is the mode of an area
  polygons: string[]; // Array of polygons, each element is a coordinate string of a polygon
  names: string[]; // Array of names, each element is the name of an area
  mapId: number; // Map ID
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  taskId: string; // Task ID
}
```
**Example**

```typescript
// Import 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)
  });

```

**Note**

- The coordinate point information sent to the device needs to be data in the machine coordinate system. The virtual area information obtained through the robot vacuum cleaner SDK needs to be converted according to the origin coordinates.
- After receiving the reply of the device restricted area information, the `restrictedAreaQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

#### Query Restricted Area
**Parameters**

--

**Return Value**

Promise<VirtualAreaResponse>: A Promise object representing the response result of the asynchronous operation.
```typescript
// VirtualAreaResponse object structure
interface VirtualAreaResponse {
  reqType: string; // Request type
  version: string; // Version number
  num: number; // Number of virtual areas
  modes: number[]; // Array of modes, each element is the mode of an area
  polygons: string[]; // Array of polygons, each element is a coordinate string of a polygon
  names: string[]; // Array of names, each element is the name of an area
  mapId: number; // Map ID
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  taskId: string; // Task ID
}
```
**Example**

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

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

requestVirtualArea();

// Listen for virtual wall device report information
 StreamDataNotificationCenter.on(VirtualAreaEnum.query, handleVirtualArea);

// In this method, you can get the virtual wall information reported by the device and update the redux data in the project
const handleVirtualArea = (data)=>{
  console.log(data)
}
```

**Note**

- The coordinate point data reported by the device is data in the machine coordinate system. When passed into the robot vacuum cleaner SDK, the data needs to be converted into the screen coordinate system.
- After receiving the reply of the device restricted area information, the `restrictedAreaQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

### Machine Voice
```typescript
const { requestAllVoices, requestVoiceInUse,setVoice } = useVoice(devId);
```
The machine voice function provides three methods: querying all supported device voices **requestAllVoices**, querying the currently used machine voice **requestVoiceInUse**, and setting the voice **setVoice**

#### Query Voice List
**Parameters**

--

**Return Value**

Promise<GetVoiceListResponse>: A Promise object representing the response result of the asynchronous operation.

```typescript
// GetVoiceListResponse object structure
  type GetVoiceListResponse = {
    datas: {
      auditionUrl: string // Audition link
      desc?: string // Description
      extendData: {
        extendId: number // Extend ID, used to compare with the language pack ID reported by the device to determine whether the voice pack is in use
        version: string // Version
      }
      id: number // ID
      imgUrl: string // Image link
      name: string // Name
      officialUrl: string // Official link
      productId: string // Product ID
      region: string[] // Region codes
    }[] // Array of voice data
    pageNo: number // Page number
    totalCount: number // Total number of data
  }

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

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

```
**Note**
- This function requires uploading voice files on the Tuya IoT platform before it can be used. For operation methods, please contact your account manager or submit a ticket for consultation.

#### Query Voice in Use
**Parameters**

--

**Return Value**

Promise<VoiceLanguageResponse>: A Promise object representing the response result of the asynchronous operation.

```typescript
// VoiceLanguageResponse object structure
interface VoiceLanguageResponse {
  reqType: string; // Request type
  version: string; // Version number
  id: number; // Voice language ID
  schedule: number; // Progress percentage
  status: number; // Status code
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  taskId: string; // Task ID
}
```
**Example**
```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"
// }
});
```
**Note**
- After receiving the reply of the device's currently used voice file, the `voiceLanguageQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

#### Set Voice
**Parameters**
- message (object): An object containing the parameters for setting the voice language, with the following properties:
  - id (number): Voice language ID.
  - url (string): URL of the voice language file.
  - md5 (string): MD5 value of the voice language file.

**Return Value**

Promise<VoiceLanguageResponse>: A Promise object representing the response result of the asynchronous operation.

```typescript
// VoiceLanguageResponse object structure
interface VoiceLanguageResponse {
  reqType: string; // Request type
  version: string; // Version number
  id: number; // Voice language ID
  schedule: number; // Progress percentage
  status: number; // Status code
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  taskId: string; // Task ID
}
```
**Example**
```typescript
import { useVoice,StreamDataNotificationCenter ,VoiceLanguageEnum} from '@ray-js/robot-data-stream';

const { setVoice } = useVoice(devId);

// The data here comes from the data returned by the requestAllVoices method
setVoice({
  id: extendData.extendId,
  url: officialUrl,
  md5: desc,
});

// Listen for device reports
StreamDataNotificationCenter.on(VoiceLanguageEnum.query, (data) => {
  console.log('Received voiceLanguageQry====>', data);
});
```

**Note**
- After sending the device voice, the device will periodically report the download progress of the voice file until the download is complete. Therefore, it is recommended to use event listening in the code implementation.
- After receiving the reply of the device downloading the voice file, the `voiceLanguageQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

### Machine Information
```typescript
const { requestDevInfo } = useDevInfo(devId);
```
The machine information function provides one method, requesting machine information **requestDevInfo**

#### Request Machine Information
**Parameters**

--

**Return Value**

Promise<DevInfoResponse>: A Promise object representing the response result of the asynchronous operation.

```typescript
// DevInfoResponse object structure

interface DevInfoResponse {
  reqType: string; // Request type
  version: string; // Version number
  info: string; // JSON string of device information
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  taskId: string; // Task ID
}
```
**Example**
```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);
      });

```
**Note**
- After receiving the reply of the device machine information, the `devInfoQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

### Historical Map
```typescript
const { deleteHistoryMap, changeCurrentMap,saveMap } = useHistoryMap(devId);
```
The historical map function provides three methods: saving the map **saveMap**, deleting the historical map **deleteHistoryMap**, and changing the home map **changeCurrentMap**

#### Save Map
**Parameters**

--

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure

type Response = {
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  reqType: string; // Request type
  version: string; // Version number
  taskId: string; // Task ID
}
```
**Example**

```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('Save successful')
}).catch(()=>{
  console.log('Save failed')
});

// Listen for device reports
 StreamDataNotificationCenter.on(SaveCurrentMapEnum.query, (data)=>{
  console.log(data)
 });

```

- After receiving the reply of the device saving the map, the `SaveCurrMapRst` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

#### Delete Map
**Parameters**

mapId (number): Cloud ID of the map.

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure

type Response = {
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  reqType: string; // Request type
  version: string; // Version number
  taskId: string; // Task ID
}
```

**Example**
```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('Delete successful')
  }).catch(error=>{
    console.log(error)
  })

// Listen for device reports
 StreamDataNotificationCenter.on(DeleteMapEnum.rst, ()=>{
  console.log('Received device report')
 });
```
**Note**

After receiving the reply of the device deleting the map, the `deleteMapRst` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

#### Change Home Map
**Parameters**

- mapId (number): Map ID.
- url (string): Map URL.

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure

type Response = {
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  reqType: string; // Request type
  mapId: number; // Map ID
  version: string; // Version number
  taskId: string; // Task ID
}
```
**Example**
```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('Change successful:', response);
}).catch(error => {
  console.error('Change failed:', error);
});

 StreamDataNotificationCenter.on(UseMapEnum.query, ()=>{
  console.log('Received device report')
 });

```
**Note**

After receiving the reply of the device changing the home map, the `useMapRst` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

### Room Division
```typescript
const {setPartDivision} = usePartDivision(devId);
```
Room division is a user operation behavior. This hook only provides a function for room division operation **setPartDivision**
#### Room Division
**Parameters**

- points (Point[]): Array of division points, the coordinates thrown out by the SDK method can be directly passed in.
- roomId (number): Room ID, the room to be divided.
- origin (Point): Coordinates of the map origin.

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure

type Response = {
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  reqType: string; // Request type
  version: string; // Version number
  taskId: string; // Task ID
}
```

**Example**

```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('Save successful')
}).catch(()=>{
  console.log('Save failed')
});

```

**Note**

- After receiving the reply of the device room division, the `partDivisionRst` event will be thrown, which can be listened to through the StreamDataNotificationCenter.
- The coordinates of the division line passed into the `setPartDivision` method are data in the screen coordinate system, that is, the data thrown out by the robot vacuum cleaner SDK method.

### Room Merge
```typescript
const {setPartMerge} = usePartMerge(devId);
```
Room merge is a user operation behavior. This hook only provides a function for room merge operation **setPartMerge**
#### Room Merge
**Parameters**

- ids (number[]): Array of room IDs to be merged.

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure

type Response = {
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  reqType: string; // Request type
  version: string; // Version number
  taskId: string; // Task ID
}
```
**Example**
```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('Set successful:', response);
}).catch(error => {
  console.error('Set failed:', error);
});

```
**Note**

- After receiving the reply of the device room merge, the `partMergeRst` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

### Do Not Disturb Mode

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

const { setQuiteHours ,requestQuiteHours} = useQuiteHours(devId);
```
The do not disturb mode function provides two methods: setting the do not disturb mode **setQuiteHours** and querying the do not disturb mode **requestQuiteHours**

#### Request Do Not Disturb Mode
**Parameters**

--

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure

type Response = {
  time: string[]; // Array of time periods, each element is a string in the format "start time, end time"
  day: number; // Whether there is a cross-day, 1 means yes, 0 means no.
  active: number; // Whether it is activated, 0 means not activated, 1 means activated
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  reqType: string; // Request type
  mapId: number; // Map ID
  version: string; // Version number
  taskId: string; // Task ID
}
```

**Example**

```typescript
// Import 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('Do not disturb mode data:', data);
  //  {
  //   "reqType": "quietHoursQry",
  //   "time": ["9,15", "0,18"],
  //   "version": "1.0.0",
  //   "day": 1,
  //   "taskId": "1733126622485"，
  //   "mapId":111
  // }
}).catch(error => {
  console.error('Request failed:', error);
});
```


#### Set Do Not Disturb Mode

**Parameters**

- `params` (object): An object containing the parameters for setting the do not disturb mode, with the following properties:
  - `startTime` (object): Start time, containing the following properties:
    - `hour` (number): Hour, range 0-23.
    - `minute` (number): Minute, range 0-59.
  - `endTime` (object): End time, containing the following properties:
    - `hour` (number): Hour, range 0-23.
    - `minute` (number): Minute, range 0-59.
  - `active` (number): Do not disturb mode switch, 1 means on, 0 means off.
  - `day` (number): Whether there is a cross-day, 1 means yes, 0 means no.
  - `version` (string, optional): Protocol version.

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
{ 
  reqType: string;  // Request type
  version: string;// Version number
  active: number;// Whether it is activated, 0 means not activated, 1 means activated
  time: string[];// Array of time periods, each element is a string in the format "start time, end time"
  day: number;// Whether there is a cross-day, 1 means yes, 0 means no.
  success: boolean; // Whether the request was successful
  errCode: number;// Error code, 0 means no error
  taskId: string; // Task ID
}
```

**Example**

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

// Device 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('Set successful')
    })
    .catch(() => {
     console.log('Set failed')
    });


```


### Reset Map

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

#### Reset Map
**Parameters**

--

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure

type Response = {
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  reqType: string; // Request type
  version: string; // Version number
  taskId: string; // Task ID
}
```
**Example**
```typescript
import { useResetMap } from '@ray-js/robot-data-stream';

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


setResetMap().then(response => {
  console.log('Reset map successful', response);
}).catch(error => {
  console.error('Reset map failed:', error);
});

```


### Room Property
```
const { requestRoomProperty, setRoomProperty } = useRoomProperty(devId);
```
The room property function provides two methods: setting the room property **setRoomProperty** and querying the room property **requestRoomProperty**

#### Set Room Property
**Parameters**

- message (object): An object containing the parameters for setting the room property, with the following properties:
  - suctions (string[], optional): Array of suctions.
  - cisterns (string[], optional): Array of cisterns.
  - cleanCounts (number[], optional): Array of clean counts.
  - yMops (number[], optional): Array of mops.
  - sweepMopModes (string[], optional): Array of sweep mop modes.
  - names (string[], optional): Array of names.
  - ids (number[]): Array of room IDs.

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.
```typescript
// Response object structure
type Response = {
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  reqType: string; // Request type
  version: string; // Version number
  taskId: string; // Task ID
  num:number; //Number of rooms
  mapId：number;//Map ID
    // Suction, closed - off gentle - quiet normal - normal strong - strong max - super strong, default value is ''
  suctions?: string[];
  // Mop water volume "closed"- off,"low"-low,"middle"-middle,"high"-high, default value is ''
  cisterns?: string[];
  // Clean count default value 1
  cleanCounts?: number[];
  // Mop mode 1: turn on Y-shaped mop 0: turn off Y-shaped mop -1 not set default value -1
  yMops?: number[];
  // Sweep mop mode "only_sweep": only sweep,"only_mop": only mop,"both_work": sweep and mop at the same time,"clean_before_mop": sweep before mop, default value is 'only_sweep'
  sweepMopModes?: string[];
  // Room floor type, default value -1
  floorTypes?: number[];
  // Room name, default is an empty string
  names?: string[];
  // Array of room IDs
  ids?: number[];
  // Room order
  orders?: number[];
}
```
**Example**
```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('Set successful:', response);
}).catch(error => {
  console.error('Set failed:', error);
});

```
**Note**

- When setting room properties, all room properties need to be passed in. For example, when modifying the room floor, the room name and other data also need to be sent to the device.
- The order of suctions, cisterns, etc. needs to be consistent with the order of ids. For example, if the first data of ids is the bedroom, then the first element of suctions also needs to be the suction of the bedroom.
#### Request Room Property
**Method Name**

requestRoomProperty

**Parameters**

--

**Return Value**

Refer to the return parameters of `setRoomProperty`

**Example**

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

requestRoomProperty().then(response => {
  console.log('Room property data:', response);
}).catch(error => {
  console.error('Request failed:', error);
});

```


### Schedule Task
```
const { requestSchedule, setSchedule } = useSchedule(devId);
```
The schedule task function provides two methods: setting the schedule **setSchedule** and querying the schedule **requestSchedule**

#### Set Schedule
**Parameters**
- message (object): An object containing the parameters for setting the schedule task, with the following properties:
  - list (Array<ScheduleItem>): List of schedule tasks.
  - num (number): Number of schedule tasks.

```typescript
type ScheduleItem = {
   // Suction, closed - off gentle - quiet normal - normal strong - strong max - super strong, default value is ''
  suctions?: string[];
   // Mop water volume "closed"- off,"low"-low,"middle"-middle,"high"-high, default value is ''
  cisterns?: string[];
  // Mop mode 1: turn on Y-shaped mop 0: turn off Y-shaped mop -1 not set default value -1
  yMops?: number[];
 // Sweep mop mode "only_sweep": only sweep,"only_mop": only mop,"both_work": sweep and mop at the same time,"clean_before_mop": sweep before mop, default value is 'only_sweep'
  sweepMopModes?: string[];
    // Array of room IDs, if ids is an empty array, it means the whole house is executed
  ids?: number[];
  // Whether the schedule is valid, 0: schedule off 1: schedule on
  active: number; 
  // Weekly cycle, Monday to Sunday
  cycle: number[]; 
   // Execution time, [hour, minute]
  time: number[];
};
```

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.
```typescript
// Response object structure, ScheduleItem structure is consistent with the input parameter structure
type Response ={
  reqType: string; // Request type
  version: string; // Version number
  success: boolean; // Whether the request was successful
  errCode: number; // Error code, 0 means no error
  taskId: string; // Task ID
  list: Array<ScheduleItem>;
  num: number;
};

```

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


const scheduleData = {
  list: [
    {
      // Schedule on
      active: 1,
      // Execute only once
      cycle:[0,0,0,0,0,0,0],
      // Cleaning time 8:00
      time: [8, 0],
      // Normal suction
      suctions: ['normal'],
      // Water volume off
      cisterns: ['closed'],
      // Clean only once
      cleanCounts: [1],
      // Y-shaped mop off
      yMops: [0],
      // Forbidden sweep mode
      sweepMopModes: ['only_sweep'],
      // Whole house cleaning
      ids: [],
    },
  ],
  num: 1,
};

setSchedule(scheduleData).then(response => {
  console.log('Set successful:', response);
}).catch(error => {
  console.error('Set failed:', error);
});
```

**Note**

- The schedule data needs to be sent in full. For example, if one schedule has been added, when adding the second schedule, the list data sent needs to include the data of the first schedule.

#### Query Schedule
**Parameters**

--

**Return Value**

Refer to the return parameters of the `setSchedule` method


**Example**

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

requestSchedule().then(response => {
  console.log('Schedule data:', response);
}).catch(error => {
  console.error('Request failed:', error);
});

```

### Select Room Cleaning
```
const { requestSelectRoomClean, setRoomClean } = useSelectRoomClean(devId);
```
The select room cleaning function provides two methods: setting the select room cleaning **setSpotClean** and querying the select room cleaning **requestSpotClean**

#### Set Select Room Cleaning
**Parameters**
- message (object): An object containing the parameters for setting the select room cleaning, with the following properties:
  - ids (number[]): Array of room IDs.
  - suctions (string[], optional): Array of suctions.
  - cisterns (string[], optional): Array of cisterns.
  - cleanCounts (number[], optional): Array of clean counts.
  - yMops (number[], optional): Array of mops.
  - sweepMopModes (string[], optional): Array of sweep mop modes.

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation

```typescript
// Response object structure, ScheduleItem structure is consistent with the input parameter structure
type Response ={
   reqType: string; // Request type
    version: string; // Version number
    success: boolean; // Whether the request was successful
    errCode: number; // Error code, 0 means no error
    taskId: string; // Task ID
    ids:string[];  // Array of room IDs
    suctions: string[];//Array of suctions
    cisterns:string[]; // Array of cisterns
    cleanCounts:number[];//Array of clean counts
    yMops: number[];//Array of mops 
    sweepMopModes: string[];  //Array of sweep mop modes 
};

```

**Example**

```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('Set successful');
}).catch(error => {
  console.error('Set failed:', error);
});
```

**Note**

- After receiving the reply of the device select room cleaning, the `roomCleanQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.


#### Query Select Room Cleaning
**Parameters**

--

**Return Value**

Refer to `setRoomClean`

**Example**

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

requestSelectRoomClean().then(response => {
  console.log('Cleaning data:', response);
}).catch(error => {
  console.error('Request failed:', error);
});

```

**Note**

- After receiving the reply of the device select room cleaning, the `roomCleanQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.



### Zone Cleaning

```
const { requestZoneClean, setZoneClean } = useZoneClean(devId);
```
The zone cleaning function provides two methods: setting the zone cleaning **setZoneClean** and querying the zone cleaning **requestZoneClean**

#### Set Zone Cleaning
**Parameters**
- message (object): An object containing the parameters for setting the zone cleaning, with the following properties:
  - polygons (string[]): Array of polygons, each element is a coordinate string of a polygon.
  - suctions (string[], optional): Array of suctions.
  - cisterns (string[], optional): Array of cisterns.
  - cleanCounts (number[], optional): Array of clean counts.
  - yMops (number[], optional): Array of mops.
  - sweepMopModes (string[], optional): Array of sweep mop modes.
  - names (string[], optional): Array of names.

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure
type Response ={
   reqType: string; // Request type
    version: string; // Version number
    success: boolean; // Whether the request was successful
    errCode: number; // Error code, 0 means no error
    taskId: string; // Task ID
    polygons:string[];  // Array of polygons, each element is a coordinate string of a polygon.
    suctions: string[];//Array of suctions
    cisterns:string[]; // Array of cisterns
    cleanCounts:number[];//Array of clean counts
    yMops: number[];//Array of mops 
    sweepMopModes: string[];  //Array of sweep mop modes 
    names?:string[]; //Array of names.
};

```

**Example**

```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: ['Area 1', 'Area 2'],
};

setZoneClean(spotCleanData).then(response => {
  console.log('Set successful:', response);
}).catch(error => {
  console.error('Set failed:', error);
});
```
**Note**

- After receiving the reply of the device zone cleaning, the `zoneCleanQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.
#### Query Zone Cleaning
**Parameters**

--

**Return Value**

Refer to the return value of `setZoneClean`

**Note**

- After receiving the reply of the device zone cleaning, the `zoneCleanQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.

### Spot Cleaning
```typescript
const { requestSpotClean, setSpotClean } = useSpotClean(devId);
```
The spot cleaning function provides two methods: setting the spot cleaning **setSpotClean** and querying the spot cleaning **requestSpotClean**

#### Set Spot Cleaning
**Parameters**

- message (object): An object containing the parameters for setting the spot cleaning, with the following properties:
  - polygons (string[]): Array of polygons, each element is a coordinate string of a polygon.
  - suctions (string[], optional): Array of suctions.
  - cisterns (string[], optional): Array of cisterns.
  - cleanCounts (number[], optional): Array of clean counts.
  - yMops (number[], optional): Array of mops.
  - sweepMopModes (string[], optional): Array of sweep mop modes.
  - names (string[], optional): Array of names.

**Return Value**

Promise<Response>: A Promise object representing the response result of the asynchronous operation.

```typescript
// Response object structure
type Response ={
   reqType: string; // Request type
    version: string; // Version number
    success: boolean; // Whether the request was successful
    errCode: number; // Error code, 0 means no error
    taskId: string; // Task ID
    polygons:string[];  // Array of polygons, each element is a coordinate string of a polygon.
    suctions: string[];//Array of suctions
    cisterns:string[]; // Array of cisterns
    cleanCounts:number[];//Array of clean counts
    yMops: number[];//Array of mops 
    sweepMopModes: string[];  //Array of sweep mop modes 
    names?:string[]; //Array of names.
};

```

**Example**

```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('Set spot cleaning',data)
}).catch(err=>{
  console.log(err)
})

```
**Note**

- After receiving the reply of the device spot cleaning, the `spotCleanQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.


#### Query Spot Cleaning
**Parameters**

--

**Return Value**

Refer to the return value of `setSpotClean`

**Example**

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

requestSpotClean().then(response => {
  console.log('Spot cleaning data:', response);
}).catch(error => {
  console.error('Request failed:', error);
});

```

**Note**

- After receiving the reply of the device spot cleaning, the `spotCleanQry` event will be thrown, which can be listened to through the StreamDataNotificationCenter.
