To reduce development costs and facilitate the interaction between laser navigation robot vacuums and app panels, the laser robot vacuum SDK encapsulates complex controls such as virtual walls and room properties into different APIs. You can use the APIs to easily complete data communication.
The APIs support the following features:
| Feature | Command type identifier | Direction |
|---|---|---|
| Set a virtual wall | VIRTUAL_WALL_SET | Panel->Device |
| Query a virtual wall | VIRTUAL_WALL_QUERY | Panel->Device |
| Set a no-go area | RESTRICTED_AREA_SET | Panel->Device |
| Query a no-go area | RESTRICTED_AREA_QUERY | Panel->Device |
| Set room properties | ROOM_PROPERTY_SET | Panel->Device |
| Query room properties | ROOM_PROPERTY_QUERY | Panel->Device |
| Set a selected area cleaning | ROOM_CLEAN_SET | Panel->Device |
| Query a selected area cleaning | ROOM_CLEAN_QUERY | Panel->Device |
| Set a selected zone cleaning | ZONE_CLEAN_SET | Panel->Device |
| Query a selected zone cleaning | ZONE_CLEAN_QUERY | Panel->Device |
| Set a selected spot cleaning | SPOT_CLEAN_SET | Panel->Device |
| Query a selected spot cleaning | SPOT_CLEAN_QUERY | Panel->Device |
| Set a schedule | SCHEDULE_SET | Panel->Device |
| Query a schedule | SCHEDULE_QUERY | Panel->Device |
| Set a Do not disturb (DND) period | QUIET_HOUR_SET | Panel->Device |
| Query a DND period | QUIET_HOUR_QUERY | Panel->Device |
| Split an area on the map | PART_DIVI_SET | Panel->Device |
| Merge areas on the map | PART_MERGE_SET | Panel->Device |
| Restore default areas on the map | PART_DEFAULT_SET | Panel->Device |
| Reset a map | RESET_CURR_MAP_SET | Panel->Device |
| Save a map | SAVE_CURR_MAP_SET | Panel->Device |
| Delete a map from the cloud | DELETE_CLOUD_MAP_SET | Panel->Device |
| Query a voice pack | VOICE_LANGUAGE_QUERY | Panel->Device |
| Query device information | DEV_INFO_QUERY | Panel->Device |
| Query password status | PASSWORD_STATE_QUERY | Panel->Device |
| Verify a password | PASSWORD_CHECK | Panel->Device |
| Set a password | PASSWORD_SET | Panel->Device |
| Query current room information | MCS_ROOM_INFO_QUERY | Panel->Device |
| Set furniture models | FURNITURE_MODEL_SET | Panel->Device |
| Query furniture models | FURNITURE_MODEL_QUERY | Panel->Device |
| Set device models | DEVICE_MODEL_SET | Panel->Device |
| Query device models | DEVICE_MODEL_QUERY | Panel->Device |
| Set custom carpet | CUSTOM_CARPET_SET | Panel->Device |
| Query custom carpet | CUSTOM_CARPET_QUERY | Panel->Device |
| Create a Wi-Fi heatmap | WIFI_MAP_SET | Panel->Device |
The SDK passes commands to the application through registered callback functions. Commands are triggered in the following two scenarios:
Trigger scenario: Triggered when the user performs an operation on the app panel.
| User operation | Trigger command | Trigger timing |
|---|---|---|
| Enter the map editing interface and draw a virtual wall on the map | VIRTUAL_WALL_SET |
After the user taps to confirm |
| Enter the map editing interface and set a no-go area | RESTRICTED_AREA_SET |
After the user draws a no-go area and confirms |
| Enter the map editing interface and modify the room name/cleaning parameters | ROOM_PROPERTY_SET |
Triggered immediately after the user modifies room properties |
| Enter the homepage map interface and select room cleaning | ROOM_CLEAN_SET |
After the user selects a room and taps Start Cleaning |
| Enter the homepage map interface and start the selected zone cleaning | ZONE_CLEAN_SET |
After the user draws a zone on the map and taps Start Cleaning |
| Enter the homepage map interface and start the selected spot cleaning | SPOT_CLEAN_SET |
After the user taps a spot on the map and taps Start Cleaning |
| Enter the device settings interface and create/modify a scheduled cleaning | SCHEDULE_SET |
After the user sets a scheduled task |
| Enter the device settings interface and set a DND period | QUIET_HOUR_SET |
After the user configures a DND period |
| Enter the map editing interface and split a room | PART_DIVI_SET |
After the user draws a divider on the map |
| Enter the map editing interface and merge rooms | PART_MERGE_SET |
After the user selects two rooms to merge |
| Enter the map editing interface and restore default areas | PART_DEFAULT_SET |
After the user taps the Restore Default button |
| Enter the map editing interface and reset the map | RESET_CURR_MAP_SET |
After the user taps Reset Map and confirms |
| Enter the map editing interface and save the map | SAVE_CURR_MAP_SET |
After the user taps Save Current Map |
| Enter the multi-map management interface and delete a cloud map | DELETE_CLOUD_MAP_SET |
After the user selects a map and taps delete |
| Enter the video channel and verify the password | PASSWORD_CHECK |
After the user enters the password and submits for verification |
| Enter the video channel and set the password | PASSWORD_SET |
After the user sets a new password |
| Set furniture models | FURNITURE_MODEL_SET |
After the user configures on the furniture management interface and saves |
| Set device models | DEVICE_MODEL_SET |
After the user configures on the device management interface and saves |
| Set custom carpet | CUSTOM_CARPET_SET |
After the user configures on the floor material interface and taps confirm |
| Enable/Cancel Wi-Fi heatmap | WIFI_MAP_SET |
After the user enters the Wi-Fi heatmap page |
Process:
User operation → app panel → cloud → SDK parsing → FUNC_SET_CB callback → application processing → Call the response interface to report results
Trigger scenario: Triggered when the user opens the app panel or performs a pull-to-refresh.
| Query command | Trigger timing | Expected response |
|---|---|---|
VIRTUAL_WALL_QUERY |
Enter the homepage map page | Return all virtual walls on the current map |
RESTRICTED_AREA_QUERY |
Enter the homepage map page | Return all no-go areas on the current map |
ROOM_PROPERTY_QUERY |
Enter the homepage map page | Return property information for all rooms |
ROOM_CLEAN_QUERY |
Enter the selected area cleaning page | Return the last selected area cleaning configuration |
ZONE_CLEAN_QUERY |
Enter the selected zone cleaning page | Return the last selected zone cleaning parameters |
SPOT_CLEAN_QUERY |
Enter the selected spot cleaning page | Return the last selected spot cleaning configuration |
SCHEDULE_QUERY |
Enter the scheduled task page | Return all scheduled cleaning tasks |
QUIET_HOUR_QUERY |
Enter the DND setting page | Return the DND period configuration |
VOICE_LANGUAGE_QUERY |
Enter the voice settings page | Return the current voice pack status |
DEV_INFO_QUERY |
Enter the device settings page | Return detailed device information |
MAP_EMPTY_QUERY |
App homepage map loading (backup feature) | Return whether map data exists |
PASSWORD_STATE_QUERY |
Enter the password settings page | Return whether a password has been set |
MCS_ROOM_INFO_QUERY |
Alexa voice control | Return the current room where the device is located |
FURNITURE_MODEL_QUERY |
Enter the homepage map page | Return the list of furniture models |
CUSTOM_CARPET_QUERY |
Enter or refresh the floor material page | Return the list of custom carpets |
DEVICE_MODEL_QUERY |
Enter the homepage map page | Return the list of device models |
Process:
Panel refresh → cloud → SDK parsing → FUNC_QUERY_CB callback → application queries data → Call the response interface to report results
Feature: A virtual wall is a virtual barrier line set on the map, and the robot will not cross the line to clean.
Data structure:
/**
* @brief Forbidden modes
*/
typedef enum {
FORBIT_ALL = 0, // All prohibited
FORBIT_SWEEP, // Prohibit mopping
FORBIT_MOP, // Prohibit sweeping
FORBIT_RESERVE, // Not set, reserved
} FORBIT_MODE_E;
/**
* @brief Coordinate point structure
*/
typedef struct {
int x; // X value of the coordinate point
int y; // Y value of the coordinate point
} POINT_COOR_S;
/**
* @brief Virtual line coordinate structure
*/
typedef struct {
FORBIT_MODE_E mode; // Forbidden mode
POINT_COOR_S points[2]; // Endpoints of the line, first element is the starting point of the virtual wall, second element is the ending point of the virtual wall
} VIRTUAL_LINE_S;
/**
* @brief Virtual wall structure
*/
typedef struct {
int num; // Number of virtual walls
int map_id; // Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
VIRTUAL_LINE_S* line; // Virtual wall coordinate points and forbidden mode
} VIRTUAL_WALL_S;
Struct description:
| Field | Type | SET command processing | QUERY command response | Proactive reporting |
|---|---|---|---|---|
num |
int | Receive the number of virtual walls set via the panel | Populate the total number of virtual walls | Populate the total number of virtual walls |
map_id |
int | Not sent by the panel. Ignore this field | Must populate the current map ID | Must populate the current map ID |
line |
Array pointer | Parse the coordinates and mode of each virtual wall | Populate information for all virtual walls | Populate information for all virtual walls |
line[i].mode |
Enum | Virtual wall mode (All-prohibited, no-go, and no-mop) | Populate the virtual wall mode | Populate the virtual wall mode |
line[i].points[0] |
Coordinates | Virtual wall start point (x0, y0) | Populate the start point coordinates | Populate the start point coordinates |
line[i].points[1] |
Coordinates | Virtual wall end point (x1, y1) | Populate the end point coordinates | Populate the end point coordinates |
Example:
// Example of SET command processing
static OPERATE_RET handle_virtual_wall_set(VIRTUAL_WALL_S* p_virtual_wall)
{
PR_DEBUG("Received virtual wall setting command, number of virtual walls: %d", p_virtual_wall->num);
// Traverse all virtual walls
for(int i = 0; i < p_virtual_wall->num; i++) {
PR_DEBUG("Virtual wall [%d] mode:%d", i, p_virtual_wall->line[i].mode);
PR_DEBUG(" Start point: (%d, %d)",
p_virtual_wall->line[i].points[0].x,
p_virtual_wall->line[i].points[0].y);
PR_DEBUG(" End point: (%d, %d)",
p_virtual_wall->line[i].points[1].x,
p_virtual_wall->line[i].points[1].y);
// TODO: Save virtual wall data to device memory/persistent storage
// save_virtual_wall_to_device(i, &p_virtual_wall->line[i]); // Pseudocode. You need to implement it yourself
}
// Report the result after processing
VIRTUAL_WALL_S report_data;
report_data.num = p_virtual_wall->num;
report_data.map_id = get_current_map_id(); // Get the current map ID. Pseudocode. You need to implement it yourself
report_data.line = p_virtual_wall->line;
return ty_rvc_virtual_wall_data_response(&report_data, 0); // 0 indicates success
}
// Example of QUERY command response
static OPERATE_RET handle_virtual_wall_query(void)
{
PR_DEBUG("Received virtual wall query command");
// Get current virtual wall data from the device
VIRTUAL_WALL_S query_data;
VIRTUAL_LINE_S lines[10]; // Assume a maximum of 10 virtual walls
query_data.num = get_virtual_wall_count(); // Get the number of virtual walls. Pseudocode. You need to implement it yourself
query_data.map_id = get_current_map_id(); // Must Populate the map ID. Pseudocode. You need to implement it yourself
query_data.line = lines;
// Populate the data for each virtual wall
for(int i = 0; i < query_data.num; i++) {
// load_virtual_wall_from_device(i, &lines[i]);//Pseudocode. You need to implement it yourself
lines[i].mode = FORBIT_ALL;
lines[i].points[0].x = 100;
lines[i].points[0].y = 200;
lines[i].points[1].x = 500;
lines[i].points[1].y = 200;
}
return ty_rvc_virtual_wall_data_response(&query_data, 0);
}
Things to note:
map_id field. The device must determine the current map on its own.map_id field. Otherwise, the panel will be unable to match the data with the correct map.Actual distance = Number of grid cells × Grid resolution.line array and its associated memory are allocated and managed by the application. The SDK will not free this memory.Feature: A no-go area is a polygonal area (usually rectangular) on the map, and the robot will not enter this area to clean.
Data structure:
typedef struct {
int len; // string length
char* name; // string memory points
} STR_ELEMENT_S;
/**
* @brief Area coordinate point structure
*/
typedef struct {
int point_num; // Number of endpoints forming the area
POINT_COOR_S* point; // Endpoint coordinates forming the restricted area
} AREA_S;
/**
* @brief Virtual area structure
*/
typedef struct {
FORBIT_MODE_E mode; // Forbidden mode
AREA_S area; // Endpoint coordinates of the restricted area
STR_ELEMENT_S cur_name; // Name of the restricted area
} VIRTUAL_AREA_S;
/**
* @brief Restricted area structure
*/
typedef struct {
int num; // Number of restricted areas
int map_id; // Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
VIRTUAL_AREA_S* restrict_zone; // Coordinates and forbidden mode of the restricted area
} RESTRICTED_AREA_S;
Struct description:
| Field | Type | SET command processing | QUERY command response | Proactive reporting |
|---|---|---|---|---|
num |
int | Receive the number of no-go areas set via the panel | Populate the total number of no-go areas | Populate the total number of no-go areas |
map_id |
int | Not sent by the panel. Ignore this field | Must populate the current map ID | Must populate the current map ID |
restrict_zone |
Array pointer | Parse the information of each no-go area | Populate all no-go area information | Populate all no-go area information |
restrict_zone[i].mode |
Enum | No-go mode (All-prohibited, no-go, and no-mop) | Populate the no-go area mode | Populate the no-go area mode |
restrict_zone[i].area |
Area structure | The polygon coordinate point set for the no-go area | Populate the area coordinates | Populate the area coordinates |
restrict_zone[i].area.point_num |
int | The number of vertices of the no-go area (typically 4) |
Populate the number of vertices | Populate the number of vertices |
restrict_zone[i].area.point |
Coordinate array | The coordinates of each vertex of the no-go area | Populate the coordinates of each vertex | Populate the coordinates of each vertex |
restrict_zone[i].cur_name |
String | The name of the no-go area | Populate the name of the no-go area | Populate the name of the no-go area |
Example:
// Example of SET command processing
static OPERATE_RET handle_restricted_area_set(RESTRICTED_AREA_S* p_restricted_area)
{
PR_DEBUG("Received no-go area setting command, number of no-go areas: %d", p_restricted_area->num);
// Traverse all no-go areas
for(int i = 0; i < p_restricted_area->num; i++) {
PR_DEBUG("No-go area [%d] mode: %d", i, p_restricted_area->restrict_zone[i].mode);
PR_DEBUG(" Name: %.*s",
p_restricted_area->restrict_zone[i].cur_name.len,
p_restricted_area->restrict_zone[i].cur_name.name);
PR_DEBUG(" Number of vertices: %d",
p_restricted_area->restrict_zone[i].area.point_num);
// Traverse all vertices of the no-go area
for(int j = 0; j < p_restricted_area->restrict_zone[i].area.point_num; j++) {
PR_DEBUG(" Vertex [%d]: (%d, %d)", j,
p_restricted_area->restrict_zone[i].area.point[j].x,
p_restricted_area->restrict_zone[i].area.point[j].y);
}
// TODO: Save no-go area data to device memory/persistent storage
// save_restricted_area_to_device(i, &p_restricted_area->restrict_zone[i]);//Pseudocode. You need to implement it yourself
}
// Report the result after processing
RESTRICTED_AREA_S report_data;
report_data.num = p_restricted_area->num;
report_data.map_id = get_current_map_id(); // Get the current map ID. Pseudocode. You need to implement it yourself
report_data.restrict_zone = p_restricted_area->restrict_zone;
return ty_rvc_restricted_area_data_response(&report_data, 0); // 0 indicates success
}
// Example of QUERY command response
static OPERATE_RET handle_restricted_area_query(void)
{
PR_DEBUG("Received no-go area query command");
// Get current no-go area data from the device
RESTRICTED_AREA_S query_data;
VIRTUAL_AREA_S areas[5]; // Assume a maximum of 5 no-go areas
POINT_COOR_S area_points[5][4]; // 4 vertices per no-go area
query_data.num = get_restricted_area_count(); // Get the number of no-go areas. Pseudocode. You need to implement it yourself
query_data.map_id = get_current_map_id(); // Map ID must be filled in. Pseudocode. You need to implement it yourself
query_data.restrict_zone = areas;
// Populate the data for each no-go area
for(int i = 0; i < query_data.num; i++) {
// load_restricted_area_from_device(i, &areas[i]);//Pseudocode. You need to implement it yourself
// Example: Set the no-go area mode
areas[i].mode = FORBIT_ALL;
// Example: Set the no-go area name
areas[i].cur_name.name = "No-go area 1";
areas[i].cur_name.len = strlen(areas[i].cur_name.name);
// Example: Set the no-go area (rectangle with 4 vertices)
areas[i].area.point_num = 4;
areas[i].area.point = area_points[i];
// Populate the rectangle with the coordinates of its 4 vertices (clockwise or counterclockwise)
area_points[i][0].x = 100; area_points[i][0].y = 100; // Bottom left
area_points[i][1].x = 200; area_points[i][1].y = 100; // Bottom right
area_points[i][2].x = 200; area_points[i][2].y = 200; // Top right
area_points[i][3].x = 100; area_points[i][3].y = 200; // Top left
}
return ty_rvc_restricted_area_data_response(&query_data, 0);
}
Things to note:
map_id field. The device must determine the current map on its own.map_id field. Otherwise, the panel will be unable to match the data with the correct map.4 vertices).point_num.Actual distance = Number of grid units × Grid resolution.cur_name field must populate both the name pointer and the len (length) value.restrict_zone array, its internal point arrays, and the cur_name.name string memory are allocated and managed by the application. The SDK will not free this memory.Feature: Room property management includes configuring parameters such as room naming, cleaning mode, cleaning order, and floor type.
Data structure:
/**
* @brief Cleaning parameters
*/
typedef struct {
int valid; // Whether parameters are valid
STR_ELEMENT_S suction; // Suction setting, values as agreed by the project
STR_ELEMENT_S cistern; // Water volume setting, values as agreed by the project
int water_value; // Custom water volume level, bound to DP in project design. When cistern is empty or invalid, water_value takes effect, range 1-30, from low to high
STR_ELEMENT_S route_preference; // Route preference setting, values as agreed by the project
STR_ELEMENT_S clean_direction; // Cleaning direction setting, values as agreed by the project
bool y_mop; // Y-shaped mopping, TRUE means enabled
int clean_cnt; // Room cleaning count
} CLEAN_PARAM_S;
/**
* @brief Room property structure
*/
typedef struct {
int num; // Number of rooms
int map_id; // Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
int* ids; // Room ID numbers, each room corresponds to one ID number
STR_ELEMENT_S* sweep_mode; // room sweep mode,each room corresponds to one sweep mode
CLEAN_PARAM_S* param; // Cleaning parameters for rooms, each room corresponds to one cleaning setting parameter, param[0] corresponds to ids[0] area
int* orders; // Cleaning order for rooms, each room corresponds to one cleaning order, cleaning order is represented by non-zero Arabic numerals, smaller values indicate higher cleaning priority, zero represents the lowest priority
int* nameLabels; // Room label array, each room corresponds to one preset label ID
STR_ELEMENT_S* cus_name; // Room naming list, each room corresponds to a name, cus_name[0] corresponds to id[0]
int* floor_type; // Room floor types,each room corresponds to one floor type
} ROOM_PROPERTY_S;
Struct description:
| Field | Type | SET command processing | QUERY command response | Proactive reporting |
|---|---|---|---|---|
num |
int | Receive the number of rooms | Populate the total number of rooms | Populate the total number of rooms |
map_id |
int | Not sent by the panel. Ignore this field | Must populate the current map ID | Must populate the current map ID |
ids |
int array | Parse each room ID | Populate all room IDs | Populate all room IDs |
sweep_mode |
String array | Parse the cleaning mode (string format) | Populate the cleaning mode strings | Populate the cleaning mode strings |
param |
Cleaning parameter array | Parse cleaning parameters for each room | Populate cleaning parameters for each room | Populate cleaning parameters for each room |
param[i].valid |
int | Parameter valid flag (reserved field) | Populate the valid flag | Populate the valid flag |
param[i].suction |
String | Suction level (string format) | Populate the suction string | Populate the suction string |
param[i].cistern |
String | Water volume level (string format) | Populate the water volume string | Populate the water volume string |
param[i].water_value |
int | Custom water volume value (1-30) | Populate the water volume value | Populate the water volume value |
param[i].route_preference |
String | Route preference (string format) | Populate the route preference string | Populate the route preference string |
param[i].clean_direction |
String | Cleaning direction (string format) | Populate the cleaning direction string | Populate the cleaning direction string |
param[i].y_mop |
bool | Y-shaped mopping switch | Populate the Y-shaped mopping switch status | Populate the Y-shaped mopping switch status |
param[i].clean_cnt |
int | Cleaning times | Populate cleaning times | Populate cleaning times |
orders |
int array | Cleaning order (lower numbers indicate higher priority) | Populate the cleaning order | Populate the cleaning order |
nameLabels |
int array | Array of room tag IDs, used to express preset room types | Populate room tag IDs | Populate room tag IDs |
cus_name |
String array | Custom room names | Populate room names | Populate room names |
floor_type |
int array | Floor type (reserved field. If implemented, it must align with the panel’s floor type definitions) | Populate the floor type | Populate the floor type |
Example:
// Example of SET command processing
static OPERATE_RET handle_room_property_set(ROOM_PROPERTY_S* p_room_property)
{
PR_DEBUG("Received room property setting command, number of rooms: %d", p_room_property->num);
// Traverse all rooms
for(int i = 0; i < p_room_property->num; i++) {
PR_DEBUG("Room [%d] ID: %d", i, p_room_property->ids[i]);
// Parse room names
if(p_room_property->cus_name) {
PR_DEBUG(" Name: %d-%s",
p_room_property->cus_name[i].len,
p_room_property->cus_name[i].name);
}
// Parse the cleaning mode (string format, it needs to be converted to an enumeration)
if(p_room_property->sweep_mode) {
PR_DEBUG(" Cleaning mode: %d-%s",
p_room_property->sweep_mode[i].len,
p_room_property->sweep_mode[i].name);
// TODO: Convert the string to an enumeration value
// int mode_enum = convert_sweep_mode_str_to_enum(&p_room_property->sweep_mode[i]); //Pseudocode. You need to implement it yourself
}
// Parse the cleaning parameters
if(p_room_property->param) {
PR_DEBUG(" Suction: %d-%s",
p_room_property->param[i].suction.len,
p_room_property->param[i].suction.name);
PR_DEBUG(" Water volume: %d-%s",
p_room_property->param[i].cistern.len,
p_room_property->param[i].cistern.name);
PR_DEBUG(" Water volume value: %d", p_room_property->param[i].water_value);
PR_DEBUG(" Path preference: %d-%s",
p_room_property->param[i].route_preference.len,
p_room_property->param[i].route_preference.name);
PR_DEBUG(" Cleaning direction: %d-%s",
p_room_property->param[i].clean_direction.len,
p_room_property->param[i].clean_direction.name);
PR_DEBUG(" Y-shaped mopping: %d", p_room_property->param[i].y_mop);
PR_DEBUG(" Cleaning count: %d", p_room_property->param[i].clean_cnt);
}
// Parse cleaning order
if(p_room_property->orders) {
PR_DEBUG(" Cleaning order: %d", p_room_property->orders[i]);
}
// Parse room label
if(p_room_property->nameLabels) {
PR_DEBUG(" Room label ID: %d", p_room_property->nameLabels[i]);
}
// Parse floor type
if(p_room_property->floor_type) { // Reserved function. If implemented, it needs to be aligned with the panel floor type
PR_DEBUG(" Floor type: %d", p_room_property->floor_type[i]);
}
// TODO: Save room properties to device memory/persistent storage
// save_room_property_to_device(i, ...); //Pseudocode. You need to implement it yourself
}
// Report the result after processing
ROOM_PROPERTY_S report_data;
report_data.num = p_room_property->num;
report_data.map_id = get_current_map_id(); // Get the current map ID. Pseudocode. You need to implement it yourself
report_data.ids = p_room_property->ids;
report_data.sweep_mode = p_room_property->sweep_mode;
report_data.param = p_room_property->param;
report_data.orders = p_room_property->orders;
report_data.cus_name = p_room_property->cus_name;
report_data.floor_type = p_room_property->floor_type;
return ty_rvc_room_property_data_response(&report_data, 0); // 0 indicates success
}
// Example of QUERY command response
static OPERATE_RET handle_room_property_query(void)
{
PR_DEBUG("Received room property query command");
// Get current room property data from the device
ROOM_PROPERTY_S query_data;
int room_ids[10]; // Array of room IDs
STR_ELEMENT_S sweep_modes[10]; // Array of cleaning modes
CLEAN_PARAM_S params[10]; // Array of cleaning parameters
int orders[10]; // Array of cleaning orders
int name_labels[10]; // Array of room labels
STR_ELEMENT_S room_names[10]; // Array of room names
int floor_types[10]; // Array of floor types
query_data.num = get_room_count(); // Get the number of rooms. Pseudocode. You need to implement it yourself
query_data.map_id = get_current_map_id(); // Map ID must be filled in. Pseudocode. You need to implement it yourself
query_data.ids = room_ids;
query_data.sweep_mode = sweep_modes;
query_data.param = params;
query_data.orders = orders;
query_data.nameLabels = name_labels;
query_data.cus_name = room_names;
query_data.floor_type = floor_types;
// Populate the data for each room
for(int i = 0; i < query_data.num; i++) {
// Populate the room IDs
room_ids[i] = get_room_id(i);
// Populate the room names
room_names[i].name = get_room_name(i); // For example: "Living Room"
room_names[i].len = strlen(room_names[i].name);
// Populate cleaning mode (string format)
sweep_modes[i].name = "only_sweep"; // For example: "only_sweep","only_mop","both_work"
sweep_modes[i].len = strlen(sweep_modes[i].name);
// Populate cleaning parameters
params[i].suction.name = "strong"; // For example: closed","gentle","normal","strong","max
params[i].suction.len = strlen(params[i].suction.name);
params[i].cistern.name = "middle"; // For example: closed","low","middle","high"
params[i].cistern.len = strlen(params[i].cistern.name);
params[i].water_va// When using cisterns for reporting, water_value will not be reported. To report waterValues, you need to set cistern.name to NULL and set water_value(1-30)er_value to 0
params[i].route_preference.name = "standard"; // For example: "standard","fast","deep"
params[i].route_preference.len = strlen(params[i].route_preference.name);
params[i].clean_direction.name = "auto"; // For example: "auto","horizontal","vertical"
params[i].clean_direction.len = strlen(params[i].clean_direction.name);
params[i].y_mop = true;
params[i].clean_cnt = 2;
// Populate the cleaning order (1 highest, 0 lowest)
orders[i] = i + 1;
// Populate the room labels (Example: 0=Entrance Hall, 1=Study, 2=Hallway, 3=Bedroom, 4=Balcony, 5=Bathroom, 6=Dining Room, 7=Living Room, 8=Master Bedroom, 9=Secondary Bedroom, 10=Kitchen)
name_labels[i] = 7; // For example, Populate "Living Room" first
// Populate the floor type (reserved field)
floor_types[i] = 1; // For example: 0 = Tile, 1 = Wood Floor, 2 = Carpet
}
return ty_rvc_room_property_data_response(&query_data, 0);
}
Things to note:
map_id field. The device must determine the current map on its own.map_id field. Otherwise, the panel will be unable to match the data with the correct map.ty_rvc_room_property_data_response() within the response function of the room editing operation to report the latest room properties.sweep_mode, cus_name, suction, cistern, route_preference, and clean_direction are all in string format.name pointer and the len (length)."only_sweep" / "only_mop" / "both_work""closed" / "gentle" / "normal" / "strong" / "max""closed" / "low" / "middle" / "high""standard" / "fast" / "deep""auto" / "horizontal" / "vertical"cistern.name != NULL: The SDK will prioritize reporting by "enumerated water volume level" (corresponding to protocol field cisterns).cistern.name == NULL: The SDK will report by "custom water volume value" (corresponding to protocol field waterValues, ranging from 1 to 30, low to high).cistern.name != NULL, the SDK will report cisterns as a whole and will not report waterValues. Therefore, do not mix values: either use cistern for all rooms, or use water_value for all rooms and set all cistern.name pointers to NULL.nameLabels field corresponds to the protocol field nameLabels.-1.nameLabels[0] corresponds to the same room as ids[0] and cus_name[0].0 means the room is not included in the sorting order.ids array.ids[0] corresponds to cus_name[0], sweep_mode[0], param[0], orders[0], nameLabels[0], and floor_type[0].ids, sweep_mode, param, orders, floor_material, and room_name) and string memory (for example, suction.name, cistern.name, sweep_mode[i].name) are allocated and managed by the application. The SDK will not free this memory.Feature: Users can select one or more rooms for cleaning, and configure independent cleaning modes and parameters for each room.
Data structure:
/**
* @brief Cleaning parameters
*/
typedef struct {
int valid; // Whether parameters are valid
STR_ELEMENT_S suction; // Suction setting, values as agreed by the project
STR_ELEMENT_S cistern; // Water volume setting, values as agreed by the project
int water_value; // Custom water volume level, bound to DP in project design. When cistern is empty or invalid, water_value takes effect, range 1-30, from low to high
STR_ELEMENT_S route_preference; // Route preference setting, values as agreed by the project
STR_ELEMENT_S clean_direction; // Cleaning direction setting, values as agreed by the project
bool y_mop; // Y-shaped mopping, TRUE means enabled
int clean_cnt; // Room cleaning count
} CLEAN_PARAM_S;
/**
* @brief Selected area cleaning structure
*/
typedef struct {
int num; // Number of selected areas
int map_id; // Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
int* ids; // List of IDs for the selected area rooms
STR_ELEMENT_S* sweep_mode; // sweep mode for the selected area rooms
CLEAN_PARAM_S* param; // Cleaning parameters for selected areas, each room corresponds to one cleaning parameter, param[0] corresponds to ids[0] area, if not set valid is 0
} ROOM_CLEAN_S;
Struct description:
| Field | Type | SET command processing | QUERY command response | Proactive reporting |
|---|---|---|---|---|
num |
int | Receive the number of selected rooms | Populate the number of rooms cleaned in the last selected area cleaning task | Populate the number of rooms cleaned in the current selected area cleaning task |
map_id |
int | Not sent by the panel. Ignore this field | Must populate the current map ID | Must populate the current map ID |
ids |
int array | Parse the list of selected room IDs | Populate the last selected room ID | Populate the currently selected room ID |
sweep_mode |
String array | Parse the cleaning mode for each room (string format) | Populate the cleaning mode strings for each room | Populate the cleaning mode strings for each room |
param |
Cleaning parameter array | Parse cleaning parameters for each room | Populate cleaning parameters for each room | Populate cleaning parameters for each room |
param[i].valid |
int | Parameter valid flag (reserved field) | Populate the valid flag | Populate the valid flag |
param[i].suction |
String | Suction level (string format) | Populate the suction string | Populate the suction string |
param[i].cistern |
String | Water volume level (string format) | Populate the water volume string | Populate the water volume string |
param[i].water_value |
int | Custom water volume value (1-30) | Populate the water volume value | Populate the water volume value |
param[i].route_preference |
String | Route preference (string format) | Populate the route preference string | Populate the route preference string |
param[i].clean_direction |
String | Cleaning direction (string format) | Populate the cleaning direction string | Populate the cleaning direction string |
param[i].y_mop |
bool | Y-shaped mopping switch | Populate the Y-shaped mopping switch status | Populate the Y-shaped mopping switch status |
param[i].clean_cnt |
int | Cleaning times | Populate cleaning times | Populate cleaning times |
Example:
// Example of SET command processing
static OPERATE_RET handle_room_clean_set(ROOM_CLEAN_S* p_room_clean)
{
PR_DEBUG("Received the selected area cleaning setting command, number of rooms: %d", p_room_clean->num);
// Traverse all selected rooms
for(int i = 0; i < p_room_clean->num; i++) {
PR_DEBUG("Room [%d] ID: %d", i, p_room_clean->ids[i]);
// Parse the cleaning mode (string format, it needs to be converted to an enumeration)
if(p_room_clean->sweep_mode) {
PR_DEBUG(" Cleaning mode: %d-%s",
p_room_clean->sweep_mode[i].len,
p_room_clean->sweep_mode[i].name);
// TODO: Convert the string to an enumeration value
// int mode_enum = convert_sweep_mode_str_to_enum(&p_room_clean->sweep_mode[i]);//Pseudocode. You need to implement it yourself
}
// Parse the cleaning parameters
PR_DEBUG(" Suction: %d-%s",
p_room_clean->param[i].suction.len,
p_room_clean->param[i].suction.name);
PR_DEBUG(" Water volume: %d-%s",
p_room_clean->param[i].cistern.len,
p_room_clean->param[i].cistern.name);
PR_DEBUG(" Water volume value: %d", p_room_clean->param[i].water_value);
PR_DEBUG(" Path preference: %d-%s",
p_room_clean->param[i].route_preference.len,
p_room_clean->param[i].route_preference.name);
PR_DEBUG(" Cleaning direction: %d-%s",
p_room_clean->param[i].clean_direction.len,
p_room_clean->param[i].clean_direction.name);
PR_DEBUG(" Y-shaped mopping: %d", p_room_clean->param[i].y_mop);
PR_DEBUG(" Cleaning count: %d", p_room_clean->param[i].clean_cnt);
// TODO: Save the selected area cleaning configuration
// save_room_clean_config(i, p_room_clean->ids[i], ...);//Pseudocode. You need to implement it yourself
}
// Start the selected area cleaning task
// start_room_clean_task(p_room_clean->ids, p_room_clean->num);//Pseudocode. You need to implement it yourself
// Report the result after processing
ROOM_CLEAN_S report_data;
report_data.num = p_room_clean->num;
report_data.map_id = get_current_map_id(); // Get the current map ID. Pseudocode. You need to implement it yourself
report_data.ids = p_room_clean->ids;
report_data.sweep_mode = p_room_clean->sweep_mode;
report_data.param = p_room_clean->param;
return ty_rvc_room_clean_data_response(&report_data, 0); // 0 indicates success
}
// Example of QUERY command response
static OPERATE_RET handle_room_clean_query(void)
{
PR_DEBUG("Received the selected area cleaning query command");
// Get the last selected area cleaning configuration from the device
ROOM_CLEAN_S query_data;
int room_ids[10]; // Array of room IDs
STR_ELEMENT_S sweep_modes[10]; // Array of cleaning modes
CLEAN_PARAM_S params[10]; // Array of cleaning parameters
// Get the last selected area cleaning configuration
query_data.num = get_last_room_clean_count(); // Get the number of rooms selected last time. Pseudocode. You need to implement it yourself
query_data.map_id = get_current_map_id(); // Map ID must be filled in. Pseudocode. You need to implement it yourself
query_data.ids = room_ids;
query_data.sweep_mode = sweep_modes;
query_data.param = params;
// Populate data for each room
for(int i = 0; i < query_data.num; i++) {
// Populate room IDs
room_ids[i] = get_last_clean_room_id(i);
// Populate cleaning mode (string format)
sweep_modes[i].name = "both_work"; // For example: "only_sweep","only_mop","both_work"
sweep_modes[i].len = strlen(sweep_modes[i].name);
// Populate cleaning parameters
params[i].suction.name = "strong"; // For example: "closed","gentle","normal","strong","max"
params[i].suction.len = strlen(params[i].suction.name);
params[i].cistern.name = "high"; // For example: "closed","low","middle","high"
params[i].cistern.len = strlen(params[i].cistern.name);
params[i].water_value = 0; // When using cisterns for reporting, water_value will not be reported. To report waterValues, set cistern.name to NULL and set water_value (1-30)
params[i].route_preference.name = "standard"; // For example: "standard","fast","deep"
params[i].route_preference.len = strlen(params[i].route_preference.name);
params[i].clean_direction.name = "auto"; // For example: "auto","horizontal","vertical"
params[i].clean_direction.len = strlen(params[i].clean_direction.name);
params[i].y_mop = false;
params[i].clean_cnt = 1;
}
return ty_rvc_room_clean_data_response(&query_data, 0);
}
Things to note:
map_id field. The device must determine the current map on its own.map_id field. Otherwise, the panel will be unable to match the data with the correct map.sweep_mode, suction, cistern, route_preference, and clean_direction are all in string format.name pointer and the len (length)."only_sweep" / "only_mop" / "both_work""closed" / "gentle" / "normal" / "strong" / "max""closed" / "low" / "middle" / "high""standard" / "fast" / "deep""auto" / "horizontal" / "vertical"cistern.name != NULL: The SDK will prioritize reporting by "enumerated water volume level" (corresponding to protocol field cisterns).cistern.name == NULL: The SDK will report by "custom water volume value" (corresponding to protocol field waterValues, ranging from 1 to 30, low to high).cistern.name != NULL, the SDK will report cisterns as a whole and will not report waterValues. Therefore, do not mix values: either use cistern for all rooms, or use water_value for all rooms and set all cistern.name pointers to NULL.ids array.ids[0] corresponds to sweep_mode[0] and param[0].ids, param) and string memory (suction.name, cistern.name, and sweep_mode[i].name) are allocated and managed by the application itself. The SDK does not release this memory.Feature: Users can select any polygonal area on the map for cleaning, and cleaning parameters can be configured independently for each area.
Data structure:
/**
* @brief Area coordinate point structure
*/
typedef struct {
int point_num; // Number of endpoints forming the area
POINT_COOR_S* point; // Endpoint coordinates forming the restricted area
} AREA_S;
/**
* @brief Zone parameters structure
*/
typedef struct {
STR_ELEMENT_S mode; // Cleaning mode
CLEAN_PARAM_S param; // Cleaning parameters
AREA_S area; // Area coordinates
STR_ELEMENT_S cur_name; // Area name
} ZONE_AREA_PARAM_S;
/**
* @brief Zone cleaning structure
*/
typedef struct {
int num; // Number of zones
int map_id; // Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
ZONE_AREA_PARAM_S* clean_zone; // Cleaning parameters for zone cleaning, each zone corresponds to one cleaning parameter
} ZONE_CLEAN_S;
Struct description:
| Field | Type | SET command processing | QUERY command response | Proactive reporting |
|---|---|---|---|---|
num |
int | Receive the number of zones | Populate the number of zones cleaned in the last selected zone cleaning task | Populate the number of zones cleaned in the current selected zone cleaning task |
map_id |
int | Not sent by the panel. Ignore this field | Must populate the current map ID | Must populate the current map ID |
clean_zone |
Array of zone parameters | Parse all zone parameters | Populate the last zone parameters | Populate the current zone parameters |
clean_zone[i].mode |
String | Cleaning mode (string format) | Populate the cleaning mode strings | Populate the cleaning mode strings |
clean_zone[i].param |
Cleaning parameters | Cleaning parameters for this area | Populate cleaning parameters | Populate cleaning parameters |
clean_zone[i].param.valid |
int | Parameter valid flag (reserved field) | Populate the valid flag | Populate the valid flag |
clean_zone[i].param.suction |
String | Suction level (string format) | Populate the suction string | Populate the suction string |
clean_zone[i].param.cistern |
String | Water volume level (string format) | Populate the water volume string | Populate the water volume string |
clean_zone[i].param.water_value |
int | Custom water volume value (1-30) | Populate the water volume value | Populate the water volume value |
clean_zone[i].param.route_preference |
String | Route preference (string format) | Populate the route preference string | Populate the route preference string |
clean_zone[i].param.clean_direction |
String | Cleaning direction (string format) | Populate the cleaning direction string | Populate the cleaning direction string |
clean_zone[i].param.y_mop |
bool | Y-shaped mopping switch | Populate the Y-shaped mopping switch status | Populate the Y-shaped mopping switch status |
clean_zone[i].param.clean_cnt |
int | Cleaning times | Populate cleaning times | Populate cleaning times |
clean_zone[i].area |
Area structure | The polygon coordinate point set for the zone | Populate the area coordinates | Populate the area coordinates |
clean_zone[i].area.point_num |
int | Number of polygon vertices (typically 4) | Populate the number of vertices | Populate the number of vertices |
clean_zone[i].area.point |
Coordinate array | Coordinates of each vertex of the polygon | Populate the coordinates of each vertex | Populate the coordinates of each vertex |
clean_zone[i].cur_name |
String | Zone name | Populate the zone name | Populate the zone name |
Example:
// Example of SET command processing
static OPERATE_RET handle_zone_clean_set(ZONE_CLEAN_S* p_zone_clean)
{
PR_DEBUG("Received zone cleaning set command, number of zones: %d", p_zone_clean->num);
// Traverse all zones
for(int i = 0; i < p_zone_clean->num; i++) {
PR_DEBUG("Zone [%d]:", i);
// Parse zone name
if(p_zone_clean->clean_zone[i].cur_name.name) {
PR_DEBUG(" Name: %d-%s",
p_zone_clean->clean_zone[i].cur_name.len,
p_zone_clean->clean_zone[i].cur_name.name);
}
// Parse the cleaning mode (string format, it needs to be converted to an enumeration)
PR_DEBUG(" Cleaning mode: %d-%s",
p_zone_clean->clean_zone[i].mode.len,
p_zone_clean->clean_zone[i].mode.name);
// TODO: Convert the string to an enumeration value
// int mode_enum = convert_sweep_mode_str_to_enum(&p_zone_clean->clean_zone[i].mode);//Pseudocode. You need to implement it yourself
// Parse the cleaning parameters
CLEAN_PARAM_S* param = &p_zone_clean->clean_zone[i].param;
PR_DEBUG(" Suction: %d-%s", param->suction.len, param->suction.name);
PR_DEBUG(" Water volume: %d-%s", param->cistern.len, param->cistern.name);
PR_DEBUG(" Y-shaped mopping: %d", param->y_mop);
PR_DEBUG(" Cleaning count: %d", param->clean_cnt);
// Parse the coordinates of the zone (polygon vertices)
AREA_S* area = &p_zone_clean->clean_zone[i].area;
PR_DEBUG(" Number of vertices: %d", area->point_num);
for(int j = 0; j < area->point_num; j++) {
PR_DEBUG(" Vertex [%d]: (%d, %d)", j,
area->point[j].x, area->point[j].y);
}
// TODO: Save the zone cleaning configuration
// save_zone_clean_config(i, &p_zone_clean->clean_zone[i]);//Pseudocode. You need to implement it yourself
}
// Start the zone cleaning task
// start_zone_clean_task(p_zone_clean->clean_zone, p_zone_clean->num);//Pseudocode. You need to implement it yourself
// Report the result after processing
ZONE_CLEAN_S report_data;
report_data.num = p_zone_clean->num;
report_data.map_id = get_current_map_id(); // Get the current map ID
report_data.clean_zone = p_zone_clean->clean_zone;
return ty_rvc_zone_clean_data_response(&report_data, 0); // 0 indicates success
}
// Example of QUERY command response
static OPERATE_RET handle_zone_clean_query(void)
{
PR_DEBUG("Received zone cleaning query command");
// Get the last zone cleaning configuration from the device
ZONE_CLEAN_S query_data;
ZONE_AREA_PARAM_S zones[5]; // Assume a maximum of 5 zones
POINT_COOR_S zone_points[5][4]; // Each zone has 4 vertices (rectangles)
query_data.num = get_last_zone_clean_count(); // Get the last zone count. Pseudocode. You need to implement it yourself
query_data.map_id = get_current_map_id(); // Map ID must be filled in. Pseudocode. You need to implement it yourself
query_data.clean_zone = zones;
// Populate the data for each zone
for(int i = 0; i < query_data.num; i++) {
// Populate the zone name
zones[i].cur_name.name = "Zone 1";
zones[i].cur_name.len = strlen(zones[i].cur_name.name);
Populate cleaning mode (string format)
zones[i].mode.name = "both_work"; // For example: "only_sweep","only_mop","both_work"
zones[i].mode.len = strlen(zones[i].mode.name);
// Populate cleaning parameters
zones[i].param.suction.name = "normal"; // For example: "closed","gentle","normal","strong","max"
zones[i].param.suction.len = strlen(zones[i].param.suction.name);
zones[i].param.cistern.name = "middle"; // For example: "closed","low","middle","high"
zones[i].param.cistern.len = strlen(zones[i].param.cistern.name);
zones[i].param.water_value = 0; // When using cisterns for reporting, water_value will not be reported. To report waterValues, you need to set cistern.name to NULL and set water_value(1-30)
zones[i].param.route_preference.name = "standard"; // For example: "standard","fast","deep"
zones[i].param.route_preference.len = strlen(zones[i].param.route_preference.name);
zones[i].param.clean_direction.name = "auto"; // For example: "auto","horizontal","vertical"
zones[i].param.clean_direction.len = strlen(zones[i].param.clean_direction.name);
zones[i].param.y_mop = true;
zones[i].param.clean_cnt = 2;
// Populate the coordinates of the zone (4 vertices of the rectangle)
zones[i].area.point_num = 4;
zones[i].area.point = zone_points[i];
// Populate the rectangle with the coordinates of its 4 vertices (clockwise or counterclockwise)
zone_points[i][0].x = 100; zone_points[i][0].y = 100; // Bottom left
zone_points[i][1].x = 300; zone_points[i][1].y = 100; // Bottom right
zone_points[i][2].x = 300; zone_points[i][2].y = 300; // Top right
zone_points[i][3].x = 100; zone_points[i][3].y = 300; // Top left
}
return ty_rvc_zone_clean_data_response(&query_data, 0);
}
Things to note:
map_id field. The device must determine the current map on its own.map_id field. Otherwise, the panel will be unable to match the data with the correct map.point_num.Actual distance = Number of grid cells × Grid resolution.mode, cur_name, suction, cistern, route_preference, and clean_direction are all in string format.name pointer and the len (length)."only_sweep" / "only_mop" / "both_work""closed" / "gentle" / "normal" / "strong" / "max""closed" / "low" / "middle" / "high""standard" / "fast" / "deep""auto" / "horizontal" / "vertical"cistern.name != NULL: The SDK will prioritize reporting by "enumerated water volume level" (corresponding to protocol field cisterns).cistern.name == NULL: The SDK will report by "custom water volume value" (corresponding to protocol field waterValues, ranging from 1 to 30, low to high).cistern.name != NULL, the SDK will report cisterns as a whole and will not report waterValues. Therefore, do not mix values: either use cistern for all rooms, or use water_value for all rooms and set all cistern.name pointers to NULL.buff and nested coordinate arrays) and string memory (mode.name, suction.name, cistern.name, and cur_name.name) are allocated and managed by the application itself. The SDK does not release this memory.Feature: Users specify a spot on the map, and the robot will clean a fixed area (usually one square meter) centered on that spot.
Data structure:
/**
* @brief Spot cleaning structure
*/
typedef struct {
int num; // Number of spot cleanings
int map_id; // Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
POINT_COOR_S* points; // List of spot coordinates, each spot area corresponds to one points element
STR_ELEMENT_S* mode; // Cleaning mode for the zone, each area corresponds to one cleaning mode, mode[0] corresponds to point[0] area
CLEAN_PARAM_S* param; // Cleaning parameters for selected areas, param[0] corresponds to point[0] area, if not set valid is 0
} SPOT_CLEAN_S;
Struct description:
| Field | Type | SET command processing | QUERY command response | Proactive reporting |
|---|---|---|---|---|
num |
int | Receive the number of spots (typically 1) | Populate the number of spots cleaned in the last selected spot cleaning task | Populate the number of spots cleaned in the current selected spot cleaning task |
map_id |
int | Not sent by the panel. Ignore this field | Must populate the current map ID | Must populate the current map ID |
points |
Coordinate array | Parse the coordinates of a spot (center point) | Populate the coordinates of the last spot | Populate the coordinates of the current spot |
mode |
String array | Parse the cleaning mode (string format) | Populate the cleaning mode strings | Populate the cleaning mode strings |
param |
Cleaning parameter array | Parse cleaning parameters | Populate cleaning parameters | Populate cleaning parameters |
param[i].valid |
int | Parameter valid flag (reserved field) | Populate the valid flag | Populate the valid flag |
param[i].suction |
String | Suction level (string format) | Populate the suction string | Populate the suction string |
param[i].cistern |
String | Water volume level (string format) | Populate the water volume string | Populate the water volume string |
param[i].water_value |
int | Custom water volume value (1-30) | Populate the water volume value | Populate the water volume value |
param[i].route_preference |
String | Route preference (string format) | Populate the route preference string | Populate the route preference string |
param[i].clean_direction |
String | Cleaning direction (string format) | Populate the cleaning direction string | Populate the cleaning direction string |
param[i].y_mop |
bool | Y-shaped mopping switch | Populate the Y-shaped mopping switch status | Populate the Y-shaped mopping switch status |
param[i].clean_cnt |
int | Cleaning times | Populate cleaning times | Populate cleaning times |
Example:
// Example of SET command processing
static OPERATE_RET handle_spot_clean_set(SPOT_CLEAN_S* p_spot_clean)
{
PR_DEBUG("Received spot cleaning set command, number of spots: %d", p_spot_clean->num);
// Typically, spot cleaning num is fixed at 1
if(p_spot_clean->num != 1) {
PR_WARN("Spot cleaning number abnormal: %d, expected to be 1", p_spot_clean->num);
}
// Parse spot coordinates
for(int i = 0; i < p_spot_clean->num; i++) {
PR_DEBUG("Spot [%d] coordinates: (%d, %d)", i,
p_spot_clean->points[i].x,
p_spot_clean->points[i].y);
// Parse the cleaning mode (string format, it needs to be converted to an enumeration)
if(p_spot_clean->mode) {
PR_DEBUG(" Cleaning mode: %d-%s",
p_spot_clean->mode[i].len,
p_spot_clean->mode[i].name);
// TODO: Convert the string to an enumeration value
// int mode_enum = convert_sweep_mode_str_to_enum(&p_spot_clean->mode[i]);//Pseudocode. You need to implement it yourself
}
// Parse the cleaning parameters
PR_DEBUG(" Suction: %d-%s",
p_spot_clean->param[i].suction.len,
p_spot_clean->param[i].suction.name);
PR_DEBUG(" Water volume: %d-%s",
p_spot_clean->param[i].cistern.len,
p_spot_clean->param[i].cistern.name);
PR_DEBUG(" Y-shaped mopping: %d", p_spot_clean->param[i].y_mop);
PR_DEBUG(" Cleaning count: %d", p_spot_clean->param[i].clean_cnt);
// TODO: Save the spot cleaning configuration
// save_spot_clean_config(&p_spot_clean->points[i], ...);//Pseudocode. You need to implement it yourself
}
// Start the spot cleaning task (clean a 1 square meter area centered on this point)
// start_spot_clean_task(&p_spot_clean->points[0]);//Pseudocode. You need to implement it yourself
// Report the result after processing
SPOT_CLEAN_S report_data;
report_data.num = p_spot_clean->num;
report_data.map_id = get_current_map_id(); // Get the current map ID. Pseudocode. You need to implement it yourself
report_data.points = p_spot_clean->points;
report_data.mode = p_spot_clean->mode;
report_data.param = p_spot_clean->param;
return ty_rvc_spot_clean_data_response(&report_data, 0); // 0 indicates success
}
// Example of QUERY command response
static OPERATE_RET handle_spot_clean_query(void)
{
PR_DEBUG("Received spot cleaning query command");
// Get the last spot cleaning configuration from the device
SPOT_CLEAN_S query_data;
POINT_COOR_S spot_point; // Spot coordinates
STR_ELEMENT_S spot_mode; // Cleaning mode
CLEAN_PARAM_S spot_param; // Cleaning parameter
// Spot cleaning usually only has one spot
query_data.num = 1;
query_data.map_id = get_current_map_id(); // Map ID must be filled in. Pseudocode. You need to implement it yourself
query_data.points = &spot_point;
query_data.mode = &spot_mode;
query_data.param = &spot_param;
// Populate the spot coordinates (the position of the last spot cleaning)
spot_point.x = get_last_spot_x(); // For example: 150,Pseudocode. You need to implement it yourself
spot_point.y = get_last_spot_y(); // For example: 200,Pseudocode. You need to implement it yourself
Populate cleaning mode (string format)
spot_mode.name = "only_sweep"; // For example: "only_sweep","only_mop","both_work"
spot_mode.len = strlen(spot_mode.name);
// Populate cleaning parameters (Report the parameters sent by the panel)
spot_param.suction.name = "normal"; // For example: "closed","gentle","normal","strong","max"
spot_param.suction.len = strlen(spot_param.suction.name);
spot_param.cistern.name = "middle"; // For example: "closed","low","middle","high"
spot_param.cistern.len = strlen(spot_param.cistern.name);
spot_param.water_value = 0; // If cistern has a value, set water_value to 0
spot_param.route_preference.name = "standard"; // For example: "standard","fast","deep"
spot_param.route_preference.len = strlen(spot_param.route_preference.name);
spot_param.clean_direction.name = "auto"; // For example: "auto","horizontal","vertical"
spot_param.clean_direction.len = strlen(spot_param.clean_direction.name);
spot_param.y_mop = false;
spot_param.clean_cnt = 1;
return ty_rvc_spot_clean_data_response(&query_data, 0);
}
Things to note:
map_id field. The device must determine the current map on its own.map_id field. Otherwise, the panel will be unable to match the data with the correct map.num is usually fixed at 1, representing a single fixed spot.points coordinates.Actual distance = Number of grid cells × Grid resolution.mode, suction, cistern, route_preference, and clean_direction are all in string format.name pointer and the len (length)."only_sweep" / "only_mop" / "both_work""closed" / "gentle" / "normal" / "strong" / "max""closed" / "low" / "middle" / "high""standard" / "fast" / "deep""auto" / "horizontal" / "vertical"cistern.name != NULL: The SDK will prioritize reporting by "enumerated water volume level" (corresponding to protocol field cisterns).cistern.name == NULL: The SDK will report by "custom water volume value" (corresponding to protocol field waterValues, ranging from 1 to 30, low to high).cistern.name != NULL, the SDK will report cisterns as a whole and will not report waterValues. Therefore, do not mix values: either use cistern for all rooms, or use water_value for all rooms and set all cistern.name pointers to NULL.buff) and string memory (mode.name, suction.name, and cistern.name) are allocated and managed by the application itself. The SDK does not release this memory.Feature: Users can set up scheduled cleaning tasks, which can be executed once or repeatedly (weekly). Each task can be configured with the rooms to be cleaned and cleaning parameters.
Data structure:
/**
* @brief Scheduled time structure
*/
typedef struct {
char hour; // Scheduled hour value
char min; // Scheduled minute value
} SCHEDULE_TIME_S;
/**
* @brief Scheduled information structure
*/
typedef struct {
unsigned char active; // Scheduled switch, 0 for off, 1 for on
unsigned char cycle; // Whether to loop the schedule, value 0 indicates a one-time schedule, non-zero indicates a looping schedule, cycle's bit0~bit6 correspond to Monday~Sunday
SCHEDULE_TIME_S start_time; // Scheduled effective time
int num; // Number of rooms corresponding to each schedule
bool customed_switch; // the switch of the clean param,when it is true, the clean param of the app send is unvalid
int* ids; // Room ID categories corresponding to each schedule
STR_ELEMENT_S* mode; // List of cleaning modes, mode[0] corresponds to ids[0]
CLEAN_PARAM_S* param; // List of cleaning parameters, param[0] corresponds to ids[0]
} SCHEDULE_PARAM_S;
/**
* @brief Local schedule structure
*/
typedef struct {
int num; // Number of schedules
int map_id; // Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
SCHEDULE_PARAM_S* time_sets; // Parameter categories for each schedule
} SCHEDULE_S;
Struct description:
| Field | Type | SET command processing | QUERY command response | Proactive reporting |
|---|---|---|---|---|
num |
int | Receive the number of scheduled tasks | Populate the current number of all scheduled tasks | Populate the current number of all scheduled tasks |
map_id |
int | Not sent by the panel. Ignore this field | Must populate the current map ID | Must populate the current map ID |
time_sets |
Array of schedule parameters | Parse all scheduled task parameters | Populate all scheduled tasks | Populate all scheduled tasks |
time_sets[i].active |
unsigned char | Task status (0: off, 1: on) | Populate task on/off status | Populate task on/off status |
time_sets[i].cycle |
unsigned char | Recurring mode. 0: only once. Other values: recurring | Populate recurring mode | Populate recurring mode |
time_sets[i].start_time |
Time structure | Task execution time (hour:minute) | Populate execution time | Populate execution time |
time_sets[i].num |
int | The number of rooms to be cleaned in this task | Populate the number of rooms | Populate the number of rooms |
time_sets[i].customed_switch |
bool | Custom parameter on/off status | Populate the custom on/off status | Populate the custom on/off status |
time_sets[i].ids |
int array | IDs of rooms to be cleaned | Populate room IDs | Populate room IDs |
time_sets[i].mode |
String array | Cleaning mode for each room (string) | Populate cleaning mode | Populate cleaning mode |
time_sets[i].param |
Cleaning parameter array | Cleaning parameters for each room | Populate cleaning parameters | Populate cleaning parameters |
Example:
// Example of SET command processing
static OPERATE_RET handle_schedule_set(SCHEDULE_S* p_schedule)
{
PR_DEBUG("Received scheduled task setting command, number of scheduled tasks: %d", p_schedule->num);
// Traverse all scheduled tasks
for(int i = 0; i < p_schedule->num; i++) {
SCHEDULE_PARAM_S* task = &p_schedule->time_sets[i];
PR_DEBUG("Scheduled task [%d]:", i);
PR_DEBUG(" On/off status: %d", task->active);
PR_DEBUG(" Execution time: %02d:%02d", task->start_time.hour, task->start_time.min);
// Parse the cycle pattern
if(task->cycle == 0) {
PR_DEBUG(" Mode: Single execution");
} else {
PR_DEBUG(" Mode: Cycle execution");
// bit0 to bit6 of cycle correspond to Monday to Sunday
for(int day = 0; day < 7; day++) {
if(task->cycle & (1 << day)) {
PR_DEBUG(" Week %d", day + 1);
}
}
}
// Parse the rooms to be cleaned
PR_DEBUG(" Number of rooms to clean: %d", task->num);
for(int j = 0; j < task->num; j++) {
PR_DEBUG(" Room ID[%d]: %d", j, task->ids[j]);
}
// Check if custom cleaning parameters are used
if(task->customed_switch) {
PR_DEBUG(" Use custom cleaning parameters:");
// Parse the cleaning mode and parameters for each room
for(int j = 0; j < task->num; j++) {
if(task->mode) {
PR_DEBUG(" Room [%d] Cleaning mode: %.*s", j,
task->mode[j].len, task->mode[j].name);
}
if(task->param) {
PR_DEBUG(" Room [%d] Suction: %.*s", j,
task->param[j].suction.len,
task->param[j].suction.name);
PR_DEBUG(" Room [%d] Water volume: %.*s", j,
task->param[j].cistern.len,
task->param[j].cistern.name);
PR_DEBUG(" Room [%d] Y-shaped mopping: %d", j, task->param[j].y_mop);
PR_DEBUG(" Room [%d] Cleaning count: %d", j, task->param[j].clean_cnt);
}
}
} else {
PR_DEBUG(" Using default cleaning parameters");
}
// TODO: Save the scheduled task to device storage
// save_schedule_task(i, task);//Pseudocode. You need to implement it yourself
}
// Report the result after processing
SCHEDULE_S report_data;
report_data.num = p_schedule->num;
report_data.map_id = get_current_map_id(); // Get the current map ID. Pseudocode. You need to implement it yourself
report_data.time_sets = p_schedule->time_sets;
return ty_rvc_schedule_data_response(&report_data, 0); // 0 indicates success
}
// Example of QUERY command response
static OPERATE_RET handle_schedule_query(void)
{
PR_DEBUG("Received scheduled task query command");
// Get all scheduled tasks from the device
SCHEDULE_S query_data;
SCHEDULE_PARAM_S tasks[10]; // Assume a maximum of 10 scheduled tasks
query_data.num = get_schedule_count(); // Get the number of scheduled tasks. Pseudocode. You need to implement it yourself
query_data.map_id = get_current_map_id(); // Map ID must be filled in. Pseudocode. You need to implement it yourself
query_data.time_sets = tasks;
// Populate the data for each scheduled task
for(int i = 0; i < query_data.num; i++) {
// Populate the task on/off and time
tasks[i].active = 1; // 1=On
tasks[i].start_time.hour = 9; // 09:00
tasks[i].start_time.min = 0;
//Populate the cycle mode (bit0 to bit6 corresponds to Monday to Sunday)
tasks[i].cycle = 0x1F; // 0b00011111 = Monday to Friday
// Populate the rooms to clean
tasks[i].num = 2; // Clean 2 rooms
// Allocate and Populate the room ID array
static int room_ids[10][10]; // Static array. It should be dynamically allocated in practice
tasks[i].ids = room_ids[i];
room_ids[i][0] = 1; // Room 1
room_ids[i][1] = 2; // Room 2
// Custom parameter switch
tasks[i].customed_switch = true;
// Allocate and Populate the cleaning mode array
static STR_ELEMENT_S modes[10][10];
tasks[i].mode = modes[i];
modes[i][0].name = "both_work";
modes[i][0].len = strlen(modes[i][0].name);
modes[i][1].name = "only_sweep";
modes[i][1].len = strlen(modes[i][1].name);
// Allocate and Populate the cleaning parameter array
static CLEAN_PARAM_S params[10][10];
tasks[i].param = params[i];
for(int j = 0; j < tasks[i].num; j++) {
params[i][j].suction.name = "strong";
params[i][j].suction.len = strlen(params[i][j].suction.name);
params[i][j].cistern.name = "high";
params[i][j].cistern.len = strlen(params[i][j].cistern.name);
params[i][j].y_mop = false;
params[i][j].clean_cnt = 1;
}
}
return ty_rvc_schedule_data_response(&query_data, 0);
}
Things to note:
map_id field. The device must determine the current map on its own.map_id field. Otherwise, the panel will be unable to match the data with the correct map.cycle = 0: One-time task. It automatically becomes invalid after execution once.cycle != 0: Recurring task. bit0 to bit6 correspond to Monday through Sunday.~~cycle = 0x7F (binary 0b01111111) means executed every day.cycle = 0x1F (binary 0b00011111) means executed from Monday to Friday.cycle = 0x60 (binary 0b01100000) means executed on Saturday and Sunday.start_time.hour: 0 to 23 (24-hour clock).start_time.min: 0 to 59.customed_switch = false: Use the device’s default cleaning parameters, ignoring the mode and param fields.customed_switch = true: Use the custom cleaning parameters sent by the panel.mode, suction, cistern, route_preference, and clean_direction are all in string format.name pointer and the len (length)."only_sweep" / "only_mop" / "both_work""closed" / "gentle" / "normal" / "strong" / "max""closed" / "low" / "middle" / "high""standard" / "fast" / "deep""auto" / "horizontal" / "vertical"cistern.name != NULL: The SDK will prioritize reporting by "enumerated water volume level" (corresponding to protocol field cisterns).cistern.name == NULL: The SDK will report by "custom water volume value" (corresponding to protocol field waterValues, ranging from 1 to 30, low to high).cistern.name != NULL, the SDK will report cisterns as a whole and will not report waterValues. Therefore, do not mix values: either use cistern for all rooms, or use water_value for all rooms and set all cistern.name pointers to NULL.ids array.ids[0] corresponds to mode[0] and param[0].time_sets, ids, mode, and param) and string memory (mode[i].name, suction.name, and cistern.name) are allocated and managed by the application itself. The SDK does not release this memory.Feature: Users can set a time period during which the robot will not automatically start cleaning tasks (such as scheduled tasks), and sound and lights will be turned off to avoid disturbing the user’s rest.
Data structure:
/**
* @brief Scheduled time structure
*/
typedef struct {
char hour; // Scheduled hour value
char min; // Scheduled minute value
} SCHEDULE_TIME_S;
/**
* @brief Do not disturb settings structure
*/
typedef struct {
unsigned char active; // Do not disturb switch, 0 for off, 1 for on
unsigned char other_day; // Effective time, 0 for today, 1 for the next day
SCHEDULE_TIME_S start_time; // Do not disturb start time
SCHEDULE_TIME_S end_time; // Do not disturb end time
} QUIET_HOURS_S;
Struct description:
| Field | Type | SET command processing | QUERY command response | Proactive reporting |
|---|---|---|---|---|
active |
unsigned char | DND mode on/off status. 0: off, 1: on | Populate DND mode on/off status | Populate DND mode on/off status |
other_day |
unsigned char | End date. 0: current day, 1: the next day | Populate date flags | Populate date flags |
start_time |
Time structure | DND start time (hour:minute) | Populate start time | Populate start time |
start_time.hour |
char | Start time – hour (0–23) | Populate hours | Populate hours |
start_time.min |
char | Start time – minute (0–59) | Populate minutes | Populate minutes |
end_time |
Time structure | DND end time (hour:minute) | Populate end time | Populate end time |
end_time.hour |
char | End time – hour (0–23) | Populate hours | Populate hours |
end_time.min |
char | End time – minute (0–59) | Populate minutes | Populate minutes |
Example:
// Example of SET command processing
static OPERATE_RET handle_quiet_hours_set(QUIET_HOURS_S* p_quiet_hours)
{
PR_DEBUG("Received DND timer setting command");
// Parse DND on/off status
PR_DEBUG("DND mode: %s", p_quiet_hours->active ? "On" : "Off");
// Parse DND time period
PR_DEBUG("Start time: %02d:%02d",
p_quiet_hours->start_time.hour,
p_quiet_hours->start_time.min);
PR_DEBUG("End time: %02d:%02d %s",
p_quiet_hours->end_time.hour,
p_quiet_hours->end_time.min,
p_quiet_hours->other_day ? "(Next Day)" : "(Same Day)");
// Check for spanning-day scenarios
if(p_quiet_hours->other_day == 1) {
// Spanning-day scenarios: For example, 22:00 to 08:00 the next day
PR_DEBUG("DND period spans days");
} else {
// Same-day scenario: For example, 12:00 to 14:00
PR_DEBUG("DND period is on the same day");
}
// Calculate DND duration (example)
int start_minutes = p_quiet_hours->start_time.hour * 60 + p_quiet_hours->start_time.min;
int end_minutes = p_quiet_hours->end_time.hour * 60 + p_quiet_hours->end_time.min;
int duration;
if(p_quiet_hours->other_day == 1) {
// Span a day: From start to midnight + from midnight to end
duration = (24 * 60 - start_minutes) + end_minutes;
} else {
duration = end_minutes - start_minutes;
}
PR_DEBUG("DND duration: %d minutes (%d hours %d minutes)",
duration, duration / 60, duration % 60);
// TODO: Save DND settings to device storage
// save_quiet_hours_config(p_quiet_hours);//Pseudocode. You need to implement it yourself
// TODO: Enable/disable DND mode
if(p_quiet_hours->active) {
// enable_quiet_mode(p_quiet_hours);//Pseudocode. You need to implement it yourself
} else {
// disable_quiet_mode();//Pseudocode. You need to implement it yourself
}
// Report the result after processing
QUIET_HOURS_S report_data = *p_quiet_hours;
return ty_rvc_quiet_hours_data_response(&report_data, 0); // 0 indicates success
}
// Example of QUERY command response
static OPERATE_RET handle_quiet_hours_query(void)
{
PR_DEBUG("Received DND timer query command");
// Get current DND settings from device
QUIET_HOURS_S query_data;
// Populate DND on/off status
query_data.active = get_quiet_mode_status(); // 0=off, 1=on. Pseudocode. You need to implement it yourself
// Populate DND time period
query_data.start_time.hour = 22; // 22:00
query_data.start_time.min = 0;
query_data.end_time.hour = 8; // 08:00
query_data.end_time.min = 0;
// Check if it spans a day (if the end time is earlier than the start time)
if(query_data.end_time.hour < query_data.start_time.hour ||
(query_data.end_time.hour == query_data.start_time.hour &&
query_data.end_time.min < query_data.start_time.min)) {
query_data.other_day = 1; // Spanning a day: 22:00 to 08:00 the next day
} else {
query_data.other_day = 0; // Same day: 12:00 to 14:00
}
return ty_rvc_quiet_hours_data_response(&query_data, 0);
}
Things to note:
hour: 0 to 23 (24-hour clock).min: 0 to 59.other_day = 0: Same day (for example, 12:00 to 14:00).other_day = 1: Crosses midnight (for example, 22:00 to 08:00 the next day).other_day = 0).other_day = 1)other_day = 0)Feature: Users can split a room into two separate rooms by drawing a divider on the map, which facilitates zoning management and cleaning.
Data structure:
/**
* @brief Division line coordinate structure
*/
typedef struct {
POINT_COOR_S points[2]; // Endpoints of the line
} DIVIDE_LINE_S;
/**
* @brief Manual partition structure
*/
typedef struct {
int num; // Number of partitions to be divided
int map_id; // Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
int* ids; // List of IDs to be divided
DIVIDE_LINE_S* divi_line; // Partition division line coordinates, each room ID corresponds to one division line, divi_line[0] corresponds to ids[0]
} PART_DIVI_S;
Struct description:
| Field | Type | SET command processing | Description |
|---|---|---|---|
num |
int | Receive the number of rooms to be split (currently only 1 is supported) | It is typically fixed at 1, indicating a single room division. |
map_id |
int | Not sent by the panel. Ignore this field | When a device reports a map, the current map ID must be populated. |
ids |
int array | Receive the ID of the room to be split | Currently, only a single room ID is supported. |
divi_line |
Divider array | Receive the coordinates of the divider | Each room ID corresponds to a divider |
divi_line[i].points[0] |
Coordinates | Starting coordinates of the divider (x0, y0) | The first endpoint of the divider |
divi_line[i].points[1] |
Coordinates | Ending coordinates of the divider (x1, y1) | The second endpoint of the divider |
Example:
// Example of SET command processing
static OPERATE_RET handle_part_division_set(PART_DIVI_S* p_part_divi)
{
PR_DEBUG("Received map area split command, number of areas: %d", p_part_divi->num);
// Currently only single room splitting is supported
if(p_part_divi->num != 1) {
PR_ERR("Batch splitting is not supported, currently only single room splitting is supported");
return ty_rvc_part_division_data_response(p_part_divi, -1);
}
// Parse the room ID to be split
int room_id = p_part_divi->ids[0];
PR_DEBUG("Room ID to be split: %d", room_id);
// Check if the room ID is valid
if(!is_valid_room_id(room_id)) { //Pseudocode. You need to implement it yourself
PR_ERR("Invalid room ID: %d", room_id);
return ty_rvc_part_division_data_response(p_part_divi, -1);
}
// Parse the coordinates of the dividing line
DIVIDE_LINE_S* line = &p_part_divi->divi_line[0];
PR_DEBUG("Start point of the dividing line: (%d, %d)", line->points[0].x, line->points[0].y);
PR_DEBUG("End point of the dividing line: (%d, %d)", line->points[1].x, line->points[1].y);
// TODO: Execute the room splitting algorithm
// 1. Verify whether the dividing line passes through the room area
// 2. Calculate the two new room areas after division
// 3. Update the map data structure
// 4. Assign new room IDs
int result = perform_room_division(room_id, line); //Room splitting algorithm (pseudocode). You need to implement it yourself
if(result != 0) {
PR_ERR("Room splitting failed");
return ty_rvc_part_division_data_response(p_part_divi, -1);
}
// Report the result after successful splitting
PART_DIVI_S report_data;
report_data.num = p_part_divi->num;
report_data.map_id = get_current_map_id(); // Map ID must be filled in
report_data.ids = p_part_divi->ids;
report_data.divi_line = p_part_divi->divi_line;
return ty_rvc_part_division_data_response(&report_data, 0);
}
Things to note:
num = 1).map_id field. The device must determine the current map on its own.map_id field. Otherwise, the panel will be unable to match the data with the correct map.Actual distance = Number of grid cells × Grid resolution.ty_rvc_room_property_data_response() to report the latest room properties.0: The room was split successfully.-1: Failed to split the room.Feature: Users can merge two adjacent rooms into one room to simplify room management or correct overly divided rooms.
Data structure:
/**
* @brief Manual area merge structure
*/
typedef struct {
int num; // Number of partitions to be merged
int map_id; // Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
int* ids; // List of IDs to be merged
} PART_MERGE_S;
Struct description:
| Field | Type | SET command processing | Description |
|---|---|---|---|
num |
int | Receive the number of rooms to be merged (currently only 2 is supported) | It is typically fixed at 2, indicating two rooms are merged. |
map_id |
int | Not sent by the panel. Ignore this field | When a device reports a map, the current map ID must be populated. |
ids |
int array | Receive the IDs of the rooms to be merged | Contain IDs of two adjacent rooms |
Example:
// Example of SET command processing
static OPERATE_RET handle_part_merge_set(PART_MERGE_S* p_part_merge)
{
PR_DEBUG("Received map area merge command, number of areas to merge: %d", p_part_merge->num);
// Currently only two room merges are supported
if(p_part_merge->num != 2) {
PR_ERR("Unsupported merge quantity, currently only two room merges are supported");
return ty_rvc_part_merge_data_response(p_part_merge, -1);
}
// Parse the IDs of the two rooms to be merged
int room_id1 = p_part_merge->ids[0];
int room_id2 = p_part_merge->ids[1];
PR_DEBUG("Rooms to be merged: %d + %d", room_id1, room_id2);
// Check if room ID is valid
if(!is_valid_room_id(room_id1) || !is_valid_room_id(room_id2)) { //Pseudocode. You need to implement it yourself
PR_ERR("Invalid room ID: %d or %d", room_id1, room_id2);
return ty_rvc_part_merge_data_response(p_part_merge, -1);
}
// Check if two rooms are adjacent
if(!are_rooms_adjacent(room_id1, room_id2)) { //Pseudocode. You need to implement it yourself
PR_ERR("Rooms are not adjacent and cannot be merged: %d and %d", room_id1, room_id2);
return ty_rvc_part_merge_data_response(p_part_merge, -1);
}
// TODO: Execute the room merging algorithm
// 1. Verify if two rooms are adjacent (shared boundary)
// 2. Merge the areas of the two rooms
// 3. Update the map data structure
// 4. Assign a new room ID or keep one of them
int result = perform_room_merge(room_id1, room_id2); // Room merging algorithm (pseudocode). You need to implement it yourself
if(result != 0) {
PR_ERR("Failed to merge the rooms");
return ty_rvc_part_merge_data_response(p_part_merge, -1);
}
// Report the result after successful merge
PART_MERGE_S report_data;
report_data.num = p_part_merge->num;
report_data.map_id = get_current_map_id(); // Map ID must be filled in. Pseudocode. You need to implement it yourself
report_data.ids = p_part_merge->ids;
return ty_rvc_part_merge_data_response(&report_data, 0);
}
Things to note:
num = 2).map_id field. The device must determine the current map on its own.map_id field. Otherwise, the panel will be unable to match the data with the correct map.ty_rvc_room_property_data_response() to report the latest room properties.0: The rooms are merged successfully.-1: Failed to merge the rooms.Feature: Restore manually edited room information to its initial default state, clearing all user operations such as room splitting, merging, and other room-related modifications.
Data structure:
/**
* @brief Manual area reset structure
*/
typedef struct {
int map_id; // Current command operation corresponding map ID
} MAP_PART_RESET_S;
Struct description:
| Field | Type | SET command processing | Description |
|---|---|---|---|
map_id |
int | The ID of the map to be restored defaults (reserved field, not sent to the panel). | Specify which map needs to have its default area restored (reserved feature). |
Example:
// Example of SET command processing
static OPERATE_RET handle_map_part_default_set(MAP_PART_RESET_S* p_part_reset)
{
// Perform the restore default area operation
// 1. Delete all manually split/merged rooms
// 2. Reload the original areas automatically split by the system
// 3. Reset room IDs and names
int map_id = get_current_map_id(); // Map ID must be filled in. Pseudocode. You need to implement it yourself
int ret = restore_default_partitions(map_id); // Restore default areas (pseudocode). You need to implement it yourself
if(ret != 0) {
PR_ERR("Failed to restore default areas");
return ty_rvc_map_part_default_data_response(p_part_reset, -1);
}
// Save the updated map data. You need to implement it yourself
save_map_data(map_id);
PR_DEBUG("Restored default areas successfully");
return ty_rvc_map_part_default_data_response(p_part_reset, 0);
}
Things to note:
ty_rvc_room_property_data_response() to report the restored room properties.0: Restored successfully.-1: Failed to restore.Feature: Clear all cached data of the current map. The device will restart the mapping process from scratch. This is suitable for scenarios such as changes in the usage environment or corrupted map data.
Data structure:
/**
* @brief Current map reset structure
*/
typedef struct {
int map_id; // Current command operation corresponding map ID
} CURRENT_MAP_RESET_S;
Struct description:
| Field | Type | SET command processing | Description |
|---|---|---|---|
map_id |
int | The ID of the map to be reset (reserved field, not sent to the panel). | Specify which map needs to have its data cleared (reserved feature). |
Example:
// Example of SET command processing
static OPERATE_RET handle_map_reset_set(CURRENT_MAP_RESET_S* p_map_reset)
{
// Check if it's the currently used map
int current_map_id = get_current_map_id(); // Get the current map ID (pseudocode). You need to implement it yourself
// Perform map reset operation
// 1. Clear map data
// 2. Clear all room information
// 3. Clear virtual walls, no-go areas, and other configurations
// 4. Clear cleaning records
int ret = clear_map_data(current_map_id); // Delete the homepage map data (pseudocode). You need to implement it yourself
if(ret != 0) {
PR_ERR("Failed to clear map data");
return ty_rvc_map_clear_data_response(p_map_reset, -1);
}
PR_DEBUG("Map reset was successful, preparing to recreate map");
return ty_rvc_map_clear_data_response(p_map_reset, 0);
}
Things to note:
map_id.ty_rvc_room_property_data_response() to report the new room properties.num = 0) can be reported.0: The map is reset successfully.-1: Failed to reset the map.Feature: Save the current map data locally or to the cloud, manage multiple floor maps, and switch and use the saved maps between different floors.
Data structure:
typedef enum {
MAP_SAVE_LOCAL = 0, // Save map locally
MAP_SAVE_CLOUD, // Save map to cloud
MAP_SAVE_MAX,
} MAP_SAVE_MODE_E;
/**
* @brief Map save structure
*/
typedef struct {
MAP_SAVE_MODE_E save_mode; // Save mode
} MAP_SAVE_S;
Struct description:
| Field | Type | SET command processing | Description |
|---|---|---|---|
save_mode |
Enum | Receive the save mode | Specify whether to save locally or in the cloud. |
Description of the save mode:
| Mode value | Enum name | Meaning | Description |
|---|---|---|---|
| 0 | MAP_SAVE_LOCAL |
Save to local | Save the map only to the device’s local storage. |
| 1 | MAP_SAVE_CLOUD |
Save to the cloud (reserved field) | Save the map to the cloud to support sync across multiple devices. |
Example:
// Example of SET command processing
static OPERATE_RET handle_map_save_set(MAP_SAVE_S* p_map_save)
{
PR_DEBUG("Received map save command, save mode: %d", p_map_save->save_mode);
// Check if the save mode is valid
if(p_map_save->save_mode >= MAP_SAVE_MAX) {
PR_ERR("Invalid save mode: %d", p_map_save->save_mode);
return ty_rvc_map_save_data_response(p_map_save, -1);
}
// Get the current map ID
int current_map_id = get_current_map_id(); // Get the current map ID (pseudocode). You need to implement it yourself
if(current_map_id <= 0) {
PR_ERR("No valid map currently");
return ty_rvc_map_save_data_response(p_map_save, -1);
}
int ret = 0;
// Save to local
ret = save_map_to_local(current_map_id); // Save to local (pseudocode). You need to implement it yourself
if(ret != 0) {
PR_ERR("Failed to save to local");
return ty_rvc_map_save_data_response(p_map_save, -1);
}
// If you need to save to the cloud
PR_DEBUG("Save map to cloud");
// Then upload to the cloud
ret = upload_map_to_cloud(current_map_id); // Save to the cloud (pseudocode). You need to implement it yourself
if(ret != 0) {
PR_ERR("Failed to upload to the cloud");
return ty_rvc_map_save_data_response(p_map_save, -1);
}
if(ret != 0) {
PR_ERR("Failed to save the map");
return ty_rvc_map_save_data_response(p_map_save, -1);
}
PR_DEBUG("Saved the map successfully");
return ty_rvc_map_save_data_response(p_map_save, 0);
}
Things to note:
MAP_SAVE_LOCAL: Save to the local storage only. Currently, the panel only supports this mode. If you want to save to the cloud, you can report to the cloud after receiving this mode.MAP_SAVE_CLOUD: Save to the cloud. For the reporting interfaces, refer to Transmit Multiple Floor Maps and Cleaning History.map_id.0: The map is saved successfully.-1: Failed to save the map.Feature: Delete the specified map data from the cloud, while also deleting the corresponding local map data (if present). This is typically used to remove floor maps that are no longer in use.
Data structure:
/**
* @brief Delete cloud map structure
*/
typedef struct {
unsigned int map_id; // Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
} DELETE_CLOUD_MAP_S;
Struct description:
| Field | Type | SET command processing | Description |
|---|---|---|---|
map_id |
unsigned int | Receive the ID of the cloud map to be deleted | Specify the map to be deleted from the cloud. |
Example:
// Example of SET command processing
static OPERATE_RET handle_delete_cloud_map_set(DELETE_CLOUD_MAP_S* p_map_delete)
{
PR_DEBUG("Received cloud map delete command, cloud map ID: %d", p_map_delete->map_id);
// Check if the map exists locally
if(!check_map_exists_in_cloud(p_map_delete->map_id)) { // Pseudocode. You need to implement it yourself
PR_ERR("The map does not exist locally: %d", p_map_delete->map_id);
return ty_rvc_map_delete_data_response(p_map_delete, 0);
}
// Delete local cache (optional)
ret = delete_local_map_cache(p_map_delete->map_id);
if(ret != 0) {
PR_ERR("Failed to delete local map");
return ty_rvc_map_delete_data_response(p_map_delete, -1);
}
PR_DEBUG("Deleted the map successfully"); //After receiving the successful local deletion response, the panel will automatically delete the cloud map data
return ty_rvc_map_delete_data_response(p_map_delete, 0);
}
Things to note:
0: The map is deleted successfully.-1: Failed to delete the map.Feature: Query the current voice pack status used by the device, allowing users to switch between voice packs of different languages in the app.
Data structure:
/**
* @brief Voice download status
*/
typedef enum {
RVC_DOWNLOAD_ST_FAILED = 0, // Voice download error
RVC_DOWNLOAD_ST_LOADING, // Voice downloading
RVC_DOWNLOAD_ST_SUCC, // Voice download successful
RVC_DOWNLOAD_ST_USING // Voice in use
} VOICE_DOWNLOAD_ST_E;
/**
* @brief Use voice response structure
*/
typedef struct {
unsigned int id; // Voice ID number
VOICE_DOWNLOAD_ST_E download_status; // Voice download status
int percent; // Voice download progress percentage,range is 0~100
} USE_VOICE_LANGUAGE_RESPONSE_S;
Struct description:
| Field | Type | QUERY command response | Proactive reporting |
|---|---|---|---|
id |
unsigned int | Populate the ID of the currently used voice pack | Populate the ID of the voice pack |
download_status |
Enum | Populate the voice pack download status | Populate the download status |
percent |
int | Populate the download progress (0-100) | Populate the download progress |
Description of download status:
| Status value | Enum name | Meaning | Scenario |
|---|---|---|---|
| 0 | RVC_DOWNLOAD_ST_FAILED |
Download failed | An error occurred while downloading the voice pack. |
| 1 | RVC_DOWNLOAD_ST_LOADING |
Downloading | Downloading the voice pack. |
| 2 | RVC_DOWNLOAD_ST_SUCC |
Download successful | The voice pack has been downloaded but not yet activated. |
| 3 | RVC_DOWNLOAD_ST_USING |
In use | The voice pack is in use. |
Things to note:
Automatic processing by the SDK:
ty_rvc_voice_download_init interface during the device initialization phase.Voice pack ID:
Progress reporting:
LOADING state: The percent field should reflect the real-time download progress (0 to 99).SUCC/USING state: The percent field should be 100.FAILED state: The percent field should be 0.Feature: Support multi-floor map management. The SDK automatically downloads floor maps to the device, and you are responsible for switching between maps as needed.
How to use:
// Called during device initialization
OPERATE_RET ret = ty_rvc_map_download_init("Pseudocode - input parameters are required here");
if(ret != OPRT_OK) {
PR_ERR("Failed to initialize map download: %d", ret);
return ret;
}
PR_DEBUG("Initialized the map download feature successfully");
Things to note:
ty_rvc_map_download_init interface during the device initialization phase.map_id).ty_rvc_room_property_data_response() to report the room properties of that map.Feature: The system verifies whether the password entered by the user is correct. Only after successful verification can the user access the protected features.
Data structure:
typedef struct {
int len; // string length
char* name; // string memory points
} STR_ELEMENT_S;
typedef struct {
STR_ELEMENT_S password;
} PASSWORD_CHECK_S;
Struct description:
| Field | Type | SET command processing | Description |
|---|---|---|---|
password |
String | Receive the password entered by the user | It needs to be compared with the stored password. |
password.name |
char* | Pointer to the password string | Actual password content. |
password.len |
int | Length of the password string | Number of bytes in the password |
Example:
// Example of SET command processing
static OPERATE_RET handle_password_check(PASSWORD_CHECK_S* p_password_check)
{
if(NULL == p_password_check || NULL == p_password_check->password.name) {
PR_ERR("Invalid password verification parameter");
return ty_rvc_password_check_response(false, 0);
}
PR_DEBUG("Password verification request received, password length: %d", p_password_check->password.len);
// Get the stored password
char stored_password[32] = {0};
int ret = read_password_from_storage(stored_password, sizeof(stored_password)); //Pseudocode. You need to implement it yourself
if(ret != 0) {
PR_ERR("Failed to read password");
return ty_rvc_password_check_response(false, 0);
}
// Compare passwords (Note: In practice, it is recommended to use encrypted hash comparison)
if(p_password_check->password.len == strlen(stored_password) &&
memcmp(p_password_check->password.name, stored_password, p_password_check->password.len) == 0) {
PR_DEBUG("Password verification was successful");
return ty_rvc_password_check_response(true, 0);
} else {
PR_WARN("Password verification failed");
return ty_rvc_password_check_response(true, 0);
}
}
Things to note:
true: The password is correct.false: The password is incorrect.password field requires both name and len.password.name) is managed by the SDK. The SDK will automatically release it after the callback function returns. If the application needs to process the data asynchronously (e.g., using it in another thread), it must copy the string to memory allocated by the application itself.Feature: Set a new password or change an existing password. The old password is required for verification when changing the password.
Data structure:
typedef struct {
int len; // string length
char* name; // string memory points
} STR_ELEMENT_S;
typedef struct {
STR_ELEMENT_S password; // New password
STR_ELEMENT_S old_password; // Old password (required when changing the password)
} PASSWORD_SET_S;
Struct description:
| Field | Type | SET command processing | Description |
|---|---|---|---|
password |
String | Receive a new password | New password to set |
password.name |
char* | Pointer to the new password string | Content of the new password |
password.len |
int | Length of the new password string | Number of bytes in the new password |
old_password |
String | Receive the old password | This is required when changing the password. It is empty when the password is set for the first time. |
old_password.name |
char* | Pointer to the old password string | Content of the old password |
old_password.len |
int | Length of the old password string | Number of bytes in the old password |
Example:
// Example of SET command processing
static OPERATE_RET handle_password_set(PASSWORD_SET_S* p_password_set)
{
if(NULL == p_password_set || NULL == p_password_set->password.name) {
PR_ERR("Invalid password setting parameter");
return ty_rvc_password_set_response(false, 0);
}
PR_DEBUG("Password setting request received, new password length: %d", p_password_set->password.len);
// Check if a password has already been set
bool password_exists = is_password_configured(); //Pseudocode. You need to implement it yourself
if(password_exists) {
// Password modification scenario: old password needs to be verified
if(NULL == p_password_set->old_password.name || p_password_set->old_password.len == 0) {
PR_ERR("Password change requires old password");
return ty_rvc_password_set_response(false, 0);
}
// Verify old password
char stored_password[32] = {0};
int ret = read_password_from_storage(stored_password, sizeof(stored_password)); //Pseudocode. You need to implement it yourself
if(ret != 0 ||
p_password_set->old_password.len != strlen(stored_password) ||
memcmp(p_password_set->old_password.name, stored_password, p_password_set->old_password.len) != 0) {
PR_ERR("Failed to verify the old password");
return ty_rvc_password_set_response(false, 0);
}
PR_DEBUG("Old password was verified successfully, starting password update");
} else {
// First password setting scenario
PR_DEBUG("First password setting");
}
// Save new password (in actual applications, it should be stored encrypted)
char new_password[32] = {0};
memcpy(new_password, p_password_set->password.name, p_password_set->password.len);
new_password[p_password_set->password.len] = '\0';
int ret = save_password_to_storage(new_password); //Pseudocode. You need to implement it yourself
if(ret != 0) {
PR_ERR("Failed to save the password");
return ty_rvc_password_set_response(false, 0);
}
PR_DEBUG("Password was set successfully");
return ty_rvc_password_set_response(true, 0);
}
Things to note:
true: The password is set successfully.false: Failed to set the password.old_password is empty. Set a new password.old_password is not empty, and you need to verify the old password first.password and old_password require the use of name and len.password.name and old_password.name) is managed by the SDK. The SDK will automatically release it after the callback function returns. If the application needs to process the data asynchronously (e.g., using it in another thread), it must copy the string to memory allocated by the application itself.Feature: Get the location information of the device’s current room, primarily for Alexa voice control scenarios. Note that the Tuya all-in-one app panel does not support this feature.
Data structure:
typedef struct {
int len; // string length
char* name; // string memory points
} STR_ELEMENT_S;
/**
* @brief MCS Room info structure
*/
typedef struct {
unsigned int map_id; //Current command operation corresponding map ID, when the device reports, it's the map ID where the device currently is, the panel uses this field to confirm whether the reported parameters and the parameters set are on the same map
unsigned int curr_name_id; //The current room ID where the machine is located.
STR_ELEMENT_S curr_name; //The current room name where the machine is located.
} MCS_ROOM_INFO_S;
Struct description:
| Field | Type | QUERY command response | Proactive reporting |
|---|---|---|---|
map_id |
unsigned int | Populate the current map ID | Populate the current map ID |
curr_name_id |
unsigned int | Populate the current room ID | Populate the current room ID |
curr_name |
String | Populate the current room name | Populate the current room name |
curr_name.name |
char* | Pointer to the room name string | Pointer to the room name string |
curr_name.len |
int | Length of the room name string | Length of the room name string |
Example:
// Example of QUERY command response
static OPERATE_RET handle_mcs_room_info_query(void)
{
PR_DEBUG("Received current room information query command");
// Prepare to report data
MCS_ROOM_INFO_S room_info;
// Populate the current map ID
room_info.map_id = get_current_map_id(); //Pseudocode. You need to implement it yourself
// Populate the current room ID
room_info.curr_name_id = get_current_room_id(); //Pseudocode. You need to implement it yourself
// Populate the current room name
char* room_name = get_current_room_name(); // For example: "living room", "bedroom", "kitchen"
if(room_name) {
room_info.curr_name.name = room_name;
room_info.curr_name.len = strlen(room_name);
} else {
// If the room name cannot be retrieved, use the default name
room_info.curr_name.name = "Unknown Room";
room_info.curr_name.len = strlen("Unknown Room");
}
PR_DEBUG("Current Location: Map ID=%d, Room ID=%d, Room Name=%.*s",
room_info.map_id,
room_info.curr_name_id,
room_info.curr_name.len,
room_info.curr_name.name);
return ty_rvc_mcs_room_info_response(&room_info, 0); // 0 indicates successful query
}
Things to note:
cur_name field must populate both the name pointer and the len (length) value.map_id must be populated with the current map ID.curr_name_id should be a valid room ID.Feature: Set and query the furniture model information recognized by the robot vacuum, enabling intelligent linkage between the map and furniture.
FURNITURE_MODEL_SET: Furniture model configuration is sent from the control panel, and the parameters are saved on the device.FURNITURE_MODEL_QUERY: The panel queries the list of furniture models configured for the current device.Data structure
/**
* @brief Model size structure
*/
typedef struct {
float length; // Length
float width; // Width
float height; // Height
} MODEL_SIZE_S;
/**
* @brief Model rotation structure (Euler angles)
*/
typedef struct {
int x; // Rotation angle around X axis
int y; // Rotation angle around Y axis
int z; // Rotation angle around Z axis
} MODEL_ROTATION_S;
/**
* @brief Model position structure
*/
typedef struct {
float x; // X coordinate in map
float y; // Y coordinate in map
float z; // Z coordinate in map (usually 0, placed on ground)
} MODEL_POSITION_S;
/**
* @brief Furniture model information structure
*/
typedef struct {
int id; // Unique identifier for the furniture model, assigned by the panel
int model_type; // Furniture type code (e.g., 0=table, 1=sofa, 2=bed, etc.)
float scale; // Scale factor, overall proportional scaling of the model, default is 1.0
MODEL_SIZE_S size; // Actual furniture dimensions [length, width, height]
MODEL_ROTATION_S rotation; // Euler angle rotation values [x, y, z], representing rotation angles around each axis
MODEL_POSITION_S position; // Furniture position in the map coordinate system [x, y, z], z is usually 0 (on the ground)
} FURNITURE_MODEL_INFO_S;
/**
* @brief Furniture model list structure
*/
typedef struct {
int model_count; // Number of models
FURNITURE_MODEL_INFO_S* models; // Array of model information
} FURNITURE_MODEL_LIST_S;
Struct description:
| Field | Type | Description |
|---|---|---|
model_count |
int | The number of furniture models. |
id |
int | The unique identifier for the furniture model, assigned by the panel. |
model_type |
int | The furniture type code. For example, 0 = dining table, 1 = sofa, and 2 = bed. The specific mapping is maintained by the frontend configuration table. |
scale |
float | Scaling factor. Scales the model size overall. Default is 1.0. |
size |
MODEL_SIZE_S | Actual dimensions of the furniture (length, width, height) in meters. |
rotation |
MODEL_ROTATION_S | Euler angle rotation values: rotation angles around the X, Y, and Z axes respectively, in degrees. |
position |
MODEL_POSITION_S | Position of the furniture in the map coordinate system, in meters. Z is typically 0 (on the ground). |
SET command processing example:
static OPERATE_RET handle_furniture_model_set(FURNITURE_MODEL_LIST_S *p_models)
{
// Save furniture models to local storage
save_furniture_models(p_models); // Pseudocode
// Report processing results
return ty_rvc_furniture_model_data_response(p_models, 0);
}
QUERY command response example:
static OPERATE_RET handle_furniture_model_query(void)
{
FURNITURE_MODEL_LIST_S query_data;
get_furniture_models(&query_data); // Pseudocode
return ty_rvc_furniture_model_data_response(&query_data, 0);
}
Things to note:
FURNITURE_MODEL_SET is triggered.FURNITURE_MODEL_QUERY to retrieve the current list of furniture models.model_count is 0, it indicates that all models should be cleared.models array) is allocated by the caller and must be released promptly after use to prevent memory leaks.Feature: Set and query the sub-device models recognized by the robot vacuum (such as smart home devices), enabling linkage between the map and devices.
DEVICE_MODEL_SET: Device model configuration is sent from the control panel in bulk, and the parameters are saved and used on the device.DEVICE_MODEL_QUERY: The panel queries the list of device models currently configured on the device.Data structure
/**
* @brief Device model information structure (with sub-device ID)
*/
typedef struct {
int id; // Unique identifier for the furniture model, assigned by the panel
int model_type; // Model type code (e.g., 0=dining table, 1=sofa, 2=bed, etc.)
float scale; // Scale ratio, globally scales the model proportionally, default is 1.0
MODEL_SIZE_S size; // Model actual dimensions [length, width, height]
MODEL_ROTATION_S rotation; // Euler angle rotation values [x, y, z], representing rotation angles around each axis
MODEL_POSITION_S position; // Model position in map coordinate system [x, y, z], z is usually 0 (placed on ground)
STR_ELEMENT_S sub_dev_id; // Sub-device ID associated with this model
} DEVICE_MODEL_INFO_S;
/**
* @brief Device model list structure
*/
typedef struct {
int model_count; // Number of models
DEVICE_MODEL_INFO_S* models; // Array of model information
} DEVICE_MODEL_LIST_S;
Struct description:
| Field | Type | Description |
|---|---|---|
model_count |
int | The number of device models. |
id |
int | The unique identifier for the device model, assigned by the panel. |
model_type |
int | The device type code. For example, 0 = socket, 1 = light, and 2 = air conditioner. The specific mapping is maintained by the frontend configuration table. |
scale |
float | Scaling factor. Scales the model size overall. Default is 1.0. |
size |
MODEL_SIZE_S | Actual dimensions of the device (length, width, height) in meters. |
rotation |
MODEL_ROTATION_S | Euler angle rotation values: rotation angles around the X, Y, and Z axes respectively, in degrees. |
position |
MODEL_POSITION_S | Position of the device in the map coordinate system, in meters. Z is typically 0 (on the ground). |
sub_dev_id |
STR_ELEMENT_S | The linked sub-device ID in a string. |
SET command processing example:
static OPERATE_RET handle_device_model_set(DEVICE_MODEL_LIST_S *p_models)
{
save_device_models(p_models); // Pseudocode
return ty_rvc_device_model_data_response(p_models, 0);
}
QUERY command response example:
static OPERATE_RET handle_device_model_query(void)
{
DEVICE_MODEL_LIST_S query_data;
get_device_models(&query_data); // Pseudocode
return ty_rvc_device_model_data_response(&query_data, 0);
}
Things to note:
DEVICE_MODEL_SET is triggered.DEVICE_MODEL_QUERY to retrieve the current list of device models.model_count is 0, it indicates that all models should be cleared.models array) is allocated by the caller and must be released promptly after use to prevent memory leaks.sub_dev_id be consistent with the unique identifier of the cloud/local sub-device.Feature: Manage carpet areas manually added by the user on the map. You can set and query carpet information, including rectangular, circular/elliptical, and custom polygonal areas. This way, the device can perform differentiated cleaning strategies depending on carpet types.
CUSTOM_CARPET_SET: The panel sends the entire custom carpet list in bulk. The device saves the list as a whole based on the current array.CUSTOM_CARPET_QUERY: The panel queries the list of custom carpets currently saved on the device.Data structure
typedef enum {
CARPET_SHAPE_UNKNOWN = 0, // Unknown carpet shape
CARPET_SHAPE_RECTANGLE, // Rectangular carpet
CARPET_SHAPE_ROUND, // Circular/Elliptical carpet
CARPET_SHAPE_CUSTOM, // Custom polygonal carpet
} CARPET_SHAPE_E;
typedef enum {
CARPET_MATERIAL_SHORT_PILE = 0, // Short-pile carpet
CARPET_MATERIAL_LONG_PILE, // Long-pile carpet
CARPET_MATERIAL_SHAG_FRINGE, // Shag/fringe carpet
CARPET_MATERIAL_FLAT_WEAVE, // Flat-weave carpet
CARPET_MATERIAL_SYNTHETIC, // Synthetic carpet
CARPET_MATERIAL_WOOL, // Wool carpet
CARPET_MATERIAL_UNKNOWN, // Unknown material
} CARPET_MATERIAL_E;
typedef struct {
int id; // Unique carpet ID (unique within the map)
CARPET_SHAPE_E shape; // Carpet shape: "rectangle", "round" (including ellipse), or "custom"
CARPET_MATERIAL_E type; // Carpet material type (affects cleaning strategy)
int cleanMode; // Cleaning attribute; this field maintains the same order as enumerations in dp: carpet_clean_prefer
int point_num; // Number of points defining the carpet area
POINT_COOR_S* point; // Array of point coordinates for the carpet area (dynamically allocated)
bool autoBoost; // Carpet auto-boost mode, 0 = disabled, 1 = enabled (consistent with dp: auto_boost)
bool fineCleaning; // Carpet fine cleaning mode, 0 = disabled, 1 = enabled (reserved field)
bool sideBrushRotating; // Side brush rotation control, 0 = disabled, 1 = enabled (reserved field)
} CUSTOM_CARPET_INFO_S;
typedef struct
{
int carpet_count; // Number of carpets
CUSTOM_CARPET_INFO_S* carpets; // Array of carpets
} CUSTOM_CARPET_LIST_S;
Struct description:
| Field | Type | Description |
|---|---|---|
carpet_count |
int | The number of custom carpets. 0 indicates clearing all carpets. |
id |
int | The unique carpet ID, assigned by the panel. |
shape |
CARPET_SHAPE_E | Carpet shape:
|
type |
CARPET_MATERIAL_E | The material type of the carpet (refer to the CARPET_MATERIAL_E type). |
cleanMode |
int | Cleaning properties. This field maintains the same order as enumerations in dp: carpet_clean_prefer. |
point_num |
int | The number of points defining the carpet area. Supports any number of points. |
point |
POINT_COOR_S* | The pointer to the array of point coordinates for the carpet area (dynamically allocated memory). Rectangles typically use 4 corner points, circular/elliptical shapes use bounding box points, and custom shapes support multiple points. |
autoBoost |
bool | The auto-boost mode.
dp: auto_boost. |
fineCleaning |
bool | Fine cleaning mode (reserved field).
|
sideBrushRotating |
bool | Side brush rotation control (reserved field).
|
SET command processing example:
static OPERATE_RET handle_custom_carpet_set(CUSTOM_CARPET_LIST_S* carpet_list)
{
// save_custom_carpet_list(carpet_list); // Pseudocode. You need to implement it yourself
return ty_rvc_custom_carpet_set_response(carpet_list, 0);
}
QUERY command response example:
static OPERATE_RET handle_custom_carpet_query(void)
{
CUSTOM_CARPET_LIST_S query_data;
// get_custom_carpet_list(&query_data); // Pseudocode. You need to implement it yourself
return ty_rvc_custom_carpet_query_response(&query_data, 0);
}
Things to note:
CUSTOM_CARPET_SET is triggered.CUSTOM_CARPET_QUERY is triggered.CUSTOM_CARPET_SET follows full overwrite semantics. When carpet_count is 0, it indicates clearing all custom carpets.points array is allocated and released by the application. Before processing commands asynchronously, you should first copy the data.Feature: Show the Wi-Fi signal strength distribution collected by the robot vacuum in the home, enabling smart map integration and network coverage analytics.
Initialization interface:
/***********************************************************
*@function: ty_rvc_wifi_map_file_init
* @brief wifi map file registration callback function for the rvc
* @param[in] path: Path where the wifi map file is stored
* @param[in] manual_flag: TRUE for manual completion of mapping, FALSE for automatic completion of mapping
* @return OPERATE_RET: 0 for success, other error codes indicate failure
***********************************************************/
OPERATE_RET ty_rvc_wifi_map_file_init(IN CONST CHAR_T* path, IN CONST BOOL_T manual_flag);
API description:
| Field | Type | Description |
|---|---|---|
path |
String | The directory path for storing the Wi-Fi heatmap file. It must not be NULL, and the length must be less than 128 bytes. |
manual_flag |
Mapping completion flag. |
|
Typical scenarios:
WIFI_MAP_SET control command is triggered. Concurrently, the SDK will enable the Wi-Fi heatmap collection switch. The next time the device cleans, the SDK will automatically collect and report the data.SET command processing example:
case WIFI_MAP_SET: {
// Upon receiving the WIFI_MAP_SET status, the service can begin cleaning and generating motion paths. Note that the paths must be reported in real time.
} break;
Things to note:
WIFI_MAP_SET command, the business logic should immediately start full-house cleaning to ensure complete Wi-Fi signal point collection during the next cleaning session.FUNC_SET_CB callback, it needs to handle the event asynchronously to ensure that frequent clicks on the panel for sending commands do not block subsequent command parsing. During asynchronous processing, the command parameters should be copied first, and then the copied data should be used for command event processing.This interface is used to register command handler callback functions. After the callback is successfully registered, the SDK receives and parses the command protocol sent by the cloud, and then calls the registered callback to execute the business functionalities. Note that the param variable in the callback will be released after the callback is invoked. If the callback has asynchronous operations, you need to copy the param data to the variable space requested by your application.
/**
* @brief Sweeper advanced function setting callback function pointer
* @param [ADVANCE_CMD_E] cmd, protocol command, the SDK uses this parameter to notify the application of the current setting command to be processed, see the list for setting commands, all ending with SET
* @param [void *] param, parameters corresponding to the command, the application converts the param parameter into the command corresponding parameter structure based on the cmd command field, the structure correspondence can refer to the accompanying demo
*/
typedef OPERATE_RET (*FUNC_SET_CB)(IN ADVANCE_CMD_E cmd, IN void* param);
/**
* @brief Sweeper advanced function query callback function pointer
* @param [ADVANCE_CMD_E] cmd, protocol command, the SDK uses this parameter to notify the application of the current query command to be processed, see the list for query commands, all ending with QUERY
* @param [void *] param, parameters corresponding to the command, current query command, its parameters are meaningless and do not need to be processed
* @note When the application gets the corresponding command parameters in the query callback function and needs to report, please call the corresponding response reporting function, for example, after processing the VIRTUAL_WALL_QUERY command, when needing to report parameters, use the ty_rvc_virtual_wall_data_response interface to report
*/
typedef OPERATE_RET (*FUNC_QUERY_CB)(IN ADVANCE_CMD_E cmd, IN void* param);
/**
* @brief Register advanced capability setting and query callback functions
* @param[in] sets_handler: Command setting callback function that the application needs to implement
* @param[in] query_handler: Command query callback function that the application needs to implement
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_advance_func_register(IN FUNC_SET_CB sets_handler, IN FUNC_QUERY_CB query_handler);
| Parameter | Description |
|---|---|
| sets_handler | This request parameter is the handler callback of the set command. It is implemented by the business application. Register with the SDK through this interface, and the param request parameter of the callback is a command parameter. The application converts this parameter into the specified command parameter struct according to the command type, and then uses it. |
| query_handler | This request parameter is the handler callback of the query command. It is implemented by the business application. Register with the SDK through this interface. The param request parameter of the callback is not currently used, and the application does not need to care about it. |
| OPERATE_RET | The return value. OPRT_OK means successful execution, and other values mean failed execution. For the meaning of error codes, refer to definitions in the TuyaOS SDK header file. |
The device data reporting interfaces are used to complete data synchronization with Tuya-enabled apps. The following table lists the data reporting features provided by each interface:
| Interface | Feature | Remarks |
|---|---|---|
| ty_rvc_virtual_wall_data_response | Report virtual wall data | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_restricted_area_data_response | Report no-go area data | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_room_property_data_response | Report room properties data | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_room_clean_data_response | Report selected area cleaning data | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_spot_clean_data_response | Report selected spot cleaning data | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_zone_clean_data_response | Report selected zone cleaning data | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_schedule_data_response | Report schedule data | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_quiet_hours_data_response | Report DND period data | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_voice_language_data_response | Report language switching data | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_device_info_data_response | Report device information data | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_part_division_data_response | Report the result of splitting the map area | This feature is only used to return the result after the set command is executed. When the panel does not send a set command, the device does not need to call this interface for data synchronization. |
| ty_rvc_part_merge_data_response | Report the result of merging the map areas | This feature is only used to return the result after the set command is executed. When the panel does not send a set command, the device does not need to call this interface for data synchronization. |
| ty_rvc_map_part_default_data_response | Report the result of restoring default areas on the map | This feature is only used to return the result after the set command is executed. When the panel does not send a set command, the device does not need to call this interface for data synchronization. |
| ty_rvc_map_clear_data_response | Report the result of resetting the map | This feature is only used to return the result after the set command is executed. When the panel does not send a set command, the device does not need to call this interface for data synchronization. |
| ty_rvc_map_save_data_response | Report the result of saving the map | This feature is only used to return the result after the set command is executed. When the panel does not send a set command, the device does not need to call this interface for data synchronization. |
| ty_rvc_map_delete_data_response | Report the result of deleting the map | This feature is only used to return the result after the set command is executed. When the panel does not send a set command, the device does not need to call this interface for data synchronization. |
| ty_rvc_map_empty_response | Report the result of querying an empty map | This feature is only used to return the result after the query command is executed. When the panel does not send a query command, the device does not need to call this interface for data synchronization. |
| ty_rvc_password_check_response | Report the result of verifying a password | This feature is only used to return the result after the query command is executed. When the panel does not send a query command, the device does not need to call this interface for data synchronization. |
| ty_rvc_password_state_response | Report the result of querying a password status | This feature is only used to return the result after the set or query command is executed. When the panel does not send a command, the device does not need to call this interface for data synchronization. |
| ty_rvc_password_set_response | Report the result of setting a password | This feature is only used to return the result after the set command is executed. When the panel does not send a set command, the device does not need to call this interface for data synchronization. |
| ty_rvc_mcs_room_info_response | Report the result of querying the current room | When the device data changes, proactively call the interface to report the data. |
| ty_rvc_furniture_model_list_response | Report the list of furniture models | This feature is only used to return the result after the set or query command is executed. When the panel does not send a command, the device does not need to call this interface for data synchronization. |
| ty_rvc_device_model_list_response | Report the list of device models | This feature is only used to return the result after the set or query command is executed. When the panel does not send a command, the device does not need to call this interface for data synchronization. |
| ty_rvc_custom_carpet_set_response | Report the result of setting a custom carpet | This feature is only used to return the result after the set command is executed. When the panel does not send a set command, the device does not need to call this interface for data synchronization. |
| ty_rvc_custom_carpet_query_response | Report the result of querying a custom carpet | This feature is only used to return the result after the query command is executed. When the panel does not send a query command, the device does not need to call this interface for data synchronization. |
| ty_rvc_carpet_clean_set_response | Report the result of setting carpet cleaning | This feature is only used to return the result after the set command is executed. When the panel does not send a set command, the device does not need to call this interface for data synchronization. |
| ty_rvc_carpet_clean_data_response | Report the result of querying carpet cleaning | This feature is only used to return the result after the query command is executed. When the panel does not send a query command, the device does not need to call this interface for data synchronization. |
/**
* @brief Report virtual wall information
* @param[in] p_virtual_wall: Virtual wall data, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Command execution result, 0 for success, other values for failure
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_virtual_wall_data_response(VIRTUAL_WALL_S* p_virtual_wall, int errcode);
/**
* @brief Report restricted area data
* @param[in] p_restricted_area: Restricted area data input parameter, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution result corresponding to the parameter setting, 0 for success, other values for failure
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_restricted_area_data_response(RESTRICTED_AREA_S* p_restricted_area, int errcode);
/**
* @brief Report room property data
* @param[in] p_room_clean: Room property data, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution result corresponding to the parameter setting, 0 for success, other values for failure
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_room_property_data_response(ROOM_PROPERTY_S* p_room_clean, int errcode);
/**
* @brief Report selected area cleaning parameter values
* @param[in] p_room_clean: Cleaning parameter input parameter, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, no error, input parameter is 0
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_room_clean_data_response(ROOM_CLEAN_S* p_room_clean, int errcode);
/**
* @brief Report spot cleaning data
* @param[in] spot_clean_data: Spot cleaning data input parameter, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, input 0 when no error
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_spot_clean_data_response(SPOT_CLEAN_S* spot_clean_data, int errcode);
/**
* @brief Report zone cleaning data
* @param[in] p_zone_area: Zone cleaning data input parameter, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, input 0 when no error
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_zone_clean_data_response(ZONE_CLEAN_S* p_zone_area, int errcode);
/**
* @brief Partition setting reply
* @param[in] p_part_division: Partition parameters, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, input 0 when no error
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_part_division_data_response(PART_DIVI_S* p_part_division, PART_DIV_ST_E errcode);
/**
* @brief Partition merge command reply
* @param[in] p_part_merge: Partition setting reply parameters, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, input 0 when no error
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_part_merge_data_response(PART_MERGE_S* p_part_merge, PART_MERGE_ST_E errcode);
/**
* @brief Partition restore default command response
* @param[in] p_part_merge: Structure parameters, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_map_part_default_data_response(MAP_PART_RESET_S* p_part_merge, PART_RESET_ST_E errcode);
/**
* @brief Clear home map reply
* @param[in] p_map_reset: Map reset structure, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_map_clear_data_response(CURRENT_MAP_RESET_S* p_map_reset, MAP_RESET_ST_E errcode);
/**
* @brief Map save command reply
* @param[in] p_map_save: Map save reply parameter input, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Error code
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_map_save_data_response(MAP_SAVE_S* p_map_save, MAP_SAVE_ST_E errcode);
/**
* @brief Map delete command reply
* @param[in] p_map_delete: Map delete reply parameters, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Error code
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_map_delete_data_response(DELETE_CLOUD_MAP_S* p_map_delete, MAP_DELETE_ST_E errcode);
/**
* @brief Use map command reply
* @param[in] p_map_use_res: Use map reply parameters, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Error code
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_map_use_data_response(USE_CLOUD_MAP_RESPONSE_S* p_map_use_res, MAP_USE_ST_E errcode);
/**
* @brief Scheduled data report
* @param[in] p_schedule: Scheduled data, passed in by the application, parameters are defined in the structure
* @param[in] current_map_id:
* @param[in] errcode:
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_schedule_data_response(SCHEDULE_S* p_schedule, int errcode);
/**
* @brief Do not disturb scheduled data report
* @param[in] p_quiet_hours: Do not disturb scheduled data input, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Error code
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_quiet_hours_data_response(QUIET_HOURS_S* p_quiet_hours, int errcode);
/**
* @brief Voice use parameter report
* @param[in] p_voice_language_res: Voice use parameter report, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_voice_language_data_response(USE_VOICE_LANGUAGE_RESPONSE_S* p_voice_language_res, VOICE_USE_ST_E errcode);
/**
* @brief Device information report, info field is concatenated by the customer in key:value format in JSON, when the app panel displays device information, it shows each value in the order of the key list
* The panel needs to correctly configure multilingual support for each key value
* This interface is responsible for completing data reporting via the MQTT channel
*
* @param[char*] info: Application's JSON format string
* @param [int] len: String length
* @return OPERATE_RET, OPRT_OK indicates success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_device_info_data_response(char* info, int len);
/**
* @brief Report dev room info
* @param[in] room_info: Room information parameters, passed in by the application, are defined in the structure.
* @param[in] errcode: Execution result corresponding to the parameter setting, 0 for success, other values for failure
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_mcs_room_info_response(MCS_ROOM_INFO_S* room_info, int errcode);
/**
* @brief Report furniture model list
* @param[in] model_list: Furniture model list, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, 0 for success, other values for failure
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_furniture_model_list_response(IN FURNITURE_MODEL_LIST_S* model_list, int errcode);
/**
* @brief Report device model list
* @param[in] model_list: Device model list, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, 0 for success, other values for failure
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_device_model_list_response(IN DEVICE_MODEL_LIST_S* model_list, int errcode);
/**
* @brief wifi map status report
* @param[in] status: map status
* @param[in] errcode: Execution error code
* @return OPERATE_RET: on success, or an error code on failure
*/
OPERATE_RET ty_rvc_wifi_map_status_response(WIFI_MAP_ST_E status, int errcode);
/**
* @brief wifi map setting report
* @param[in] state: true:set is exist, false:set not exist
* @param[in] errcode: Execution error code
* @return OPERATE_RET: on success, or an error code on failure
*/
OPERATE_RET ty_rvc_wifi_map_rst_response(IN bool state, int errcode);
/**
* @brief Report custom carpet set response
* @param[in] carpet_list: Custom carpet list, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, 0 for success, other values for failure
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_custom_carpet_set_response(IN CUSTOM_CARPET_LIST_S* carpet_list, int errcode);
/**
* @brief Report custom carpet query response
* @param[in] carpet_list: Custom carpet list, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, 0 for success, other values for failure
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_custom_carpet_query_response(IN CUSTOM_CARPET_LIST_S* carpet_list, int errcode);
/**
* @brief Report carpet cleaning set response
* @param[in] carpet_clean: Carpet cleaning data, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, 0 for success, other values for failure
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_carpet_clean_set_response(IN CARPET_CLEAN_S* carpet_clean, int errcode);
/**
* @brief Report carpet cleaning data
* @param[in] carpet_clean: Carpet cleaning data, passed in by the application, parameters are defined in the structure
* @param[in] errcode: Execution error code, 0 for success, other values for failure
* @return OPERATE_RET: 0 success, other error codes indicate failure
*/
OPERATE_RET ty_rvc_carpet_clean_data_response(IN CARPET_CLEAN_S* carpet_clean, int errcode);
static OPERATE_RET __sweeper_advance_function_set(OUT ADVANCE_CMD_E cmd, OUT void *param)
{
OPERATE_RET ret = 0;
int i=0,j=0;
switch (cmd) {
case VIRTUAL_WALL_SET: {
VIRTUAL_WALL_S* p_virtual_wall = (VIRTUAL_WALL_S*)param;
PR_DEBUG("virtual wall num:%d", p_virtual_wall->num);
for(i = 0; i < p_virtual_wall->num;i++){
PR_DEBUG("mode:%d", p_virtual_wall->line[i].mode);
PR_DEBUG("line:%d", p_virtual_wall->line[i].points[0].x);
PR_DEBUG("line:%d", p_virtual_wall->line[i].points[0].y);
PR_DEBUG("line:%d", p_virtual_wall->line[i].points[1].x);
PR_DEBUG("line:%d", p_virtual_wall->line[i].points[1].y);
}
........
// This section only shows the how to use the interface. In actual use, the actual device data should be obtained and reported in the asynchronous event handling function.
current_map_id = 8;
errcode = 0;
ty_rvc_virtual_wall_data_response(p_virtual_wall, current_map_id, errcode);
}break;
.......
default:
PR_DEBUG("cmd not support now");
break;
}
}
static OPERATE_RET __sweeper_advance_function_query(OUT ADVANCE_CMD_E cmd, OUT void *param)
{
OPERATE_RET ret = OPRT_OK;
uint16_t cmd_index = 0;
switch(cmd){
case VIRTUAL_WALL_QUERY:{
// Demonstrate data reporting using test data
VIRTUAL_WALL_S test_virtual_wall;
VIRTUAL_LINE_S virtual_line[10] = {0};
OPERATE_RET ret = OPRT_OK;
test_virtual_wall.num = 1;
for (int i = 0; i < test_virtual_wall.num; i++) {
virtual_line[i].mode = FORBIT_ALL;
virtual_line[i].points[0].x = 100;
virtual_line[i].points[0].y = 200;
virtual_line[i].points[1].x = 50;
virtual_line[i].points[1].y = 60;
}
test_virtual_wall.line = virtual_line;
int current_map_id = 7;
ty_rvc_virtual_wall_data_response(&test_virtual_wall, current_map_id, errcode);
}break;
default:
PR_DEBUG("cmd not support now");
break;
}
return ret;
}
// Power-on main process
int main(int argc, char* argv[])
{
OPERATE_RET ret = 0;
....
ret = ty_sys_start();
if (ret != OPRT_OK) {
PR_ERR("[%s, %d] sys start failed", __FUNCTION__, __LINE__);
return ret;
}
ty_rvc_advance_func_register(__sweeper_advance_function_set, __sweeper_advance_function_query);
....
}
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback