rospogrigio / localtuya

local handling for Tuya devices
GNU General Public License v3.0
2.72k stars 532 forks source link

Device support request Honiture G20 robot vacuum cleaner #1624

Open andyb2000 opened 5 months ago

andyb2000 commented 5 months ago

The problem

Add support for Honiture G20 robot vacuum cleaner. This is very close to working but a few of the status/states don't seem to be correct.

Environment

Steps to reproduce

Add device in localtuya using defaults, set as Vacuum type. View status of device, in my case it always says it is always cleaning so the states seem incorrect

DP dump

TuyaDebug (Tuya DPs dump) [1.0.0]

Device bf051cb1514f3d5555mzwp at 192.168.x.x key REDACTED protocol 3.3 dev_type type_0a:
    DPS [2] VALUE [False] 
    DPS [3] VALUE [standby] 
    DPS [5] VALUE [charging] 
    DPS [6] VALUE [96] 
    DPS [7] VALUE [100] 
    DPS [8] VALUE [100] 
    DPS [9] VALUE [100] 
    DPS [14] VALUE [normal] 
    DPS [15] VALUE [00600504092] 
    DPS [16] VALUE [50] 
    DPS [17] VALUE [6] 
    DPS [18] VALUE [0] 
    DPS [20] VALUE [low] 
    DPS [24] VALUE [both_work] 
    DPS [101] VALUE [True] 
    DPS [102] VALUE [False] 
    DPS [104] VALUE [vol_normal] 
    DPS [105] VALUE [english] 

Additional information

Looking in the Tuya API the definitions:

power_go    Boolean 
"{true,false}"
mode    Enum    
{
  "range": [
    "standby",
    "smart",
    "wall_follow",
    "spiral",
    "chargego",
    "random"
  ]
}
direction_control   Enum    
{
  "range": [
    "forward",
    "backward",
    "turn_left",
    "turn_right",
    "stop"
  ]
}
status  Enum    
{
  "range": [
    "standby",
    "cleaning",
    "goto_charge",
    "charging",
    "charge_done",
    "smart_clean",
    "wall_clean",
    "spot_clean",
    "sleep"
  ]
}
electricity_left    Integer 
{
  "unit": "%",
  "min": 0,
  "max": 100,
  "scale": 0,
  "step": 1
}
edge_brush  Integer 
{
  "unit": "%",
  "min": 0,
  "max": 100,
  "scale": 0,
  "step": 1
}
roll_brush  Integer 
{
  "unit": "%",
  "min": 0,
  "max": 100,
  "scale": 0,
  "step": 1
}
filter  Integer 
{
  "unit": "%",
  "min": 0,
  "max": 100,
  "scale": 0,
  "step": 1
}
reset_edge_brush    Boolean 
"{true,false}"
reset_roll_brush    Boolean 
"{true,false}"
reset_filter    Boolean 
"{true,false}"
seek    Boolean 
"{true,false}"
suction Enum    
{
  "range": [
    "gentle",
    "normal",
    "strong"
  ]
}
clean_record    String  
{
  "maxlen": 255
}
clean_area  Integer 
{
  "unit": "㎡",
  "min": 0,
  "max": 9999,
  "scale": 1,
  "step": 1
}
clean_time  Integer 
{
  "unit": "min",
  "min": 0,
  "max": 9999,
  "scale": 0,
  "step": 1
}
fault   Bitmap  
{
  "label": [
    "edge_sweep",
    "middle_sweep",
    "left_wheel",
    "right_wheel",
    "garbage_box",
    "land_check",
    "collision",
    "give_up",
    "low_power",
    "fan",
    "dwheel",
    "uwheel"
  ]
}
cistern Enum    
{
  "range": [
    "low",
    "middle",
    "high"
  ]
}
language    Enum    
{
  "range": [
    "english",
    "german",
    "french",
    "italian",
    "spanish",
    "japanese"
  ]
}

Is there a way to export that with a reference to the DP values to map them?

andyb2000 commented 5 months ago

Also the debug output from localtuya for the device:

{
  "home_assistant": {
    "installation_type": "Home Assistant OS",
    "version": "2024.1.0",
    "dev": false,
    "hassio": true,
    "virtualenv": false,
    "python_version": "3.11.6",
    "docker": true,
    "arch": "x86_64",
    "timezone": "Europe/London",
    "os_name": "Linux",
    "os_version": "6.1.59",
    "supervisor": "2023.12.0",
    "host_os": "Home Assistant OS 11.1",
    "docker_version": "24.0.6",
    "chassis": "embedded",
    "run_as_root": true
  },
  "custom_components": {
    "zha_toolkit": {
      "version": "v1.1.6",
      "requirements": [
        "pytz"
      ]
    },
    "hildebrandglow_dcc": {
      "version": "1.0.3",
      "requirements": [
        "pyglowmarkt==0.5.5"
      ]
    },
    "alexa_media": {
      "version": "4.6.5",
      "requirements": [
        "alexapy==1.27.6",
        "packaging>=20.3",
        "wrapt>=1.14.0"
      ]
    },
    "hacs": {
      "version": "1.33.0",
      "requirements": [
        "aiogithubapi>=22.10.1"
      ]
    },
    "auto_backup": {
      "version": "1.4.1",
      "requirements": []
    },
    "eventsensor": {
      "version": "3.3.1",
      "requirements": []
    },
    "better_thermostat": {
      "version": "1.4.0",
      "requirements": []
    },
    "hello_service": {
      "version": "0.1.0",
      "requirements": []
    },
    "bluetooth_tracker": {
      "version": "1.0.0",
      "requirements": [
        "bt-proximity==0.2.1",
        "git+https://github.com/pybluez/pybluez.git#pybluez==0.30"
      ]
    },
    "localtuya": {
      "version": "5.2.1",
      "requirements": []
    },
    "mikrotik_router": {
      "version": "0.0.0",
      "requirements": [
        "librouteros>=3.2.0",
        "mac-vendor-lookup>=0.1.12"
      ]
    },
    "gardena_smart_system": {
      "version": "1.0.0",
      "requirements": [
        "py-smart-gardena==1.3.7"
      ]
    },
    "templatebinarysensor": {
      "version": "0.0.2",
      "requirements": []
    },
    "hottubmanager": {
      "version": "0.1",
      "requirements": []
    }
  },
  "integration_manifest": {
    "domain": "localtuya",
    "name": "LocalTuya integration",
    "codeowners": [
      "@rospogrigio",
      "@postlund"
    ],
    "config_flow": true,
    "dependencies": [],
    "documentation": "https://github.com/rospogrigio/localtuya/",
    "iot_class": "local_push",
    "issue_tracker": "https://github.com/rospogrigio/localtuya/issues",
    "requirements": [],
    "version": "5.2.1",
    "is_built_in": false
  },
  "data": {
    "device_config": {
      "friendly_name": "RoboVac",
      "host": "192.168.X.REDACTED",
      "device_id": "REDACTED",
      "local_key": "REDACTED",
      "protocol_version": "3.3",
      "enable_debug": false,
      "model": "G20",
      "dps_strings": [
        "2 (value: False)",
        "3 (value: standby)",
        "5 (value: charging)",
        "6 (value: 92)",
        "7 (value: 100)",
        "8 (value: 100)",
        "9 (value: 100)",
        "14 (value: normal)",
        "15 (value: 00600504092)",
        "16 (value: 50)",
        "17 (value: 6)",
        "18 (value: 0)",
        "20 (value: low)",
        "24 (value: both_work)",
        "101 (value: True)",
        "102 (value: False)",
        "104 (value: vol_normal)",
        "105 (value: english)"
      ],
      "entities": [
        {
          "id": 2,
          "friendly_name": "RoboVac",
          "idle_status_value": "standby,sleep",
          "powergo_dp": 5,
          "docked_status_value": "charging,charge_done",
          "returning_status_value": "goto_charge",
          "modes": "standby,smart,wall_follow,spiral,chargego,random",
          "return_mode": "chargego",
          "fan_speeds": "gentle,normal,strong",
          "paused_state": "paused",
          "stop_status": "standby",
          "battery_dp": 6,
          "mode_dp": 3,
          "fan_speed_dp": 14,
          "platform": "vacuum"
        }
      ],
      "product_key": "REDACTED"
    },
    "device_cloud_info": {
      "active_time": 1705045111,
      "biz_type": 18,
      "category": "sd",
      "create_time": 1704915753,
      "icon": "smart/icon/bay1597905160549l20L/824e637609fad68a7de501be6064dc6f.png",
      "id": "REDACTED",
      "ip": "195.97.X.REDACTED",
      "lat": "REDACTED",
      "local_key": "REDACTED",
      "lon": "REDACTED",
      "model": "G20",
      "name": "Albert",
      "online": true,
      "owner_id": "REDACTED",
      "product_id": "REDACTED",
      "product_name": "G20",
      "status": [
        {
          "code": "power_go",
          "value": false
        },
        {
          "code": "mode",
          "value": "standby"
        },
        {
          "code": "direction_control",
          "value": "stop"
        },
        {
          "code": "status",
          "value": "charging"
        },
        {
          "code": "electricity_left",
          "value": 92
        },
        {
          "code": "edge_brush",
          "value": 100
        },
        {
          "code": "roll_brush",
          "value": 100
        },
        {
          "code": "filter",
          "value": 100
        },
        {
          "code": "reset_edge_brush",
          "value": false
        },
        {
          "code": "reset_roll_brush",
          "value": false
        },
        {
          "code": "reset_filter",
          "value": false
        },
        {
          "code": "seek",
          "value": false
        },
        {
          "code": "suction",
          "value": "normal"
        },
        {
          "code": "clean_record",
          "value": "00600504092"
        },
        {
          "code": "clean_area",
          "value": 50
        },
        {
          "code": "clean_time",
          "value": 6
        },
        {
          "code": "fault",
          "value": 0
        },
        {
          "code": "cistern",
          "value": "low"
        },
        {
          "code": "language",
          "value": "english"
        }
      ],
      "sub": false,
      "time_zone": "+00:00",
      "uid": "REDACTED",
      "update_time": 1705063350,
      "uuid": "REDACTED"
    }
  }
}

On the back of this, a suggestion to add a 'simple' guide, how to translate the information in the Tuya API data into the LocalTuya "Config entity" dialogue to set the correct values for each of the requests.

andyb2000 commented 5 months ago

I think I'm getting there with this! Querying properties, I get this list. So if I add this dp list then try to match them up this should work?

I still get always "Cleaning" so I'm obviously setting one value incorrectly.

{
  "result": {
    "properties": [
      {
        "code": "switch_go",
        "custom_name": "",
        "dp_id": 2,
        "time": 1705145024310,
        "value": false
      },
      {
        "code": "mode",
        "custom_name": "",
        "dp_id": 3,
        "time": 1705145024363,
        "value": "standby"
      },
      {
        "code": "direction_control",
        "custom_name": "",
        "dp_id": 4,
        "time": 1705144912509,
        "value": "stop"
      },
      {
        "code": "status",
        "custom_name": "",
        "dp_id": 5,
        "time": 1705147124238,
        "value": "charge_done"
      },
      {
        "code": "battery_percentage",
        "custom_name": "",
        "dp_id": 6,
        "time": 1705147124258,
        "value": 100
      },
      {
        "code": "edge_brush_life",
        "custom_name": "",
        "dp_id": 7,
        "time": 1705139683790,
        "value": 99
      },
      {
        "code": "roll_brush_life",
        "custom_name": "",
        "dp_id": 8,
        "time": 1705045116511,
        "value": 100
      },
      {
        "code": "filter_life",
        "custom_name": "",
        "dp_id": 9,
        "time": 1705045116550,
        "value": 100
      },
      {
        "code": "edge_brush_life_reset",
        "custom_name": "",
        "dp_id": 10,
        "time": 1704915753098,
        "value": false
      },
      {
        "code": "roll_brush_life_reset",
        "custom_name": "",
        "dp_id": 11,
        "time": 1704915753098,
        "value": false
      },
      {
        "code": "filter_reset",
        "custom_name": "",
        "dp_id": 12,
        "time": 1704915753098,
        "value": false
      },
      {
        "code": "seek",
        "custom_name": "",
        "dp_id": 13,
        "time": 1704915753098,
        "value": false
      },
      {
        "code": "suction",
        "custom_name": "",
        "dp_id": 14,
        "time": 1705144978982,
        "value": "normal"
      },
      {
        "code": "clean_record",
        "custom_name": "",
        "dp_id": 15,
        "time": 1705140702915,
        "value": "03002204096"
      },
      {
        "code": "clean_area",
        "custom_name": "",
        "dp_id": 16,
        "time": 1705144916618,
        "value": 3
      },
      {
        "code": "clean_time",
        "custom_name": "",
        "dp_id": 17,
        "time": 1705144892615,
        "value": 0
      },
      {
        "code": "fault",
        "custom_name": "",
        "dp_id": 18,
        "time": 1705067504233,
        "value": 0
      },
      {
        "code": "map_config",
        "custom_name": "",
        "dp_id": 19,
        "time": 1705045115904,
        "value": "AQD/"
      },
      {
        "code": "water_control",
        "custom_name": "",
        "dp_id": 20,
        "time": 1705045117498,
        "value": "low"
      },
      {
        "code": "work_mode",
        "custom_name": "",
        "dp_id": 24,
        "time": 1705045117523,
        "value": "both_work"
      },
      {
        "code": "bostiq",
        "custom_name": "",
        "dp_id": 101,
        "time": 1705045117564,
        "value": true
      },
      {
        "code": "carpet",
        "custom_name": "",
        "dp_id": 102,
        "time": 1705045117592,
        "value": false
      },
      {
        "code": "volume",
        "custom_name": "",
        "dp_id": 104,
        "time": 1705045117620,
        "value": "vol_normal"
      },
      {
        "code": "language",
        "custom_name": "",
        "dp_id": 105,
        "time": 1705045117661,
        "value": "english"
      }
    ]
  },
andyb2000 commented 5 months ago

I think I've almost got this sorted (Sorry, I'd missed the WIKI information on DPs)

To help others, I've managed to capture various states and the DP information like this:

Cleaning 
87% battery
13.9 area
17min time
AUTO mode
Smart mode
suction: normal
water: low
carpet booster: true
carpet mode: false
comsumable: filter 100%
side brush 94%
main brush 97%

Device bf051cb1514f3d5555mzwp:
    DPS [2] VALUE [True] ON?
    DPS [3] VALUE [smart]  -- MODE
    DPS [4] VALUE [stop] 
    DPS [5] VALUE [smart_clean] -- MODE
    DPS [6] VALUE [88] -- BATTERY
    DPS [7] VALUE [94] -- SIDE BRUSH
    DPS [8] VALUE [97] -- MAIN BRUSH
    DPS [9] VALUE [100] -- FILTER
    DPS [14] VALUE [normal] -- suction
    DPS [15] VALUE [03302204147] mapid?
    DPS [16] VALUE [138] -- area
    DPS [17] VALUE [17] -- cleaning time
    DPS [18] VALUE [0] 
    DPS [20] VALUE [low] -- water
    DPS [24] VALUE [both_work] 
    DPS [101] VALUE [True] -- carpet booster
    DPS [102] VALUE [False] -- carpet mode
    DPS [104] VALUE [vol_normal] -- volume
    DPS [105] VALUE [english] -- language

collision fault
standby
74%
19.2 cleaning area
27min cleaning
Device bf051cb1514f3d5555mzwp:
    DPS [2] VALUE [False] 
    DPS [3] VALUE [standby] 
    DPS [4] VALUE [stop] 
    DPS [5] VALUE [standby] 
    DPS [6] VALUE [74] 
    DPS [7] VALUE [94] 
    DPS [8] VALUE [97] 
    DPS [9] VALUE [100] 
    DPS [14] VALUE [strong] 
    DPS [15] VALUE [03302204147] 
    DPS [16] VALUE [192] -- area
    DPS [17] VALUE [27] -- cleaning time
    DPS [18] VALUE [64] -- fault id?  64 = collision?
    DPS [20] VALUE [low] 
    DPS [24] VALUE [both_work] 
    DPS [101] VALUE [True] 
    DPS [102] VALUE [False] 
    DPS [104] VALUE [vol_normal] 
    DPS [105] VALUE [english] 

Wheel fault:
Device bf051cb1514f3d5555mzwp:
    DPS [2] VALUE [False] 
    DPS [3] VALUE [standby] 
    DPS [4] VALUE [stop] 
    DPS [5] VALUE [standby] 
    DPS [6] VALUE [53] 
    DPS [7] VALUE [94] 
    DPS [8] VALUE [97] 
    DPS [9] VALUE [100] 
    DPS [14] VALUE [normal] 
    DPS [15] VALUE [03302204147] 
    DPS [16] VALUE [150] 
    DPS [17] VALUE [16] 
    DPS [18] VALUE [1024]  -- fault id?  1024 = wheel fault
    DPS [20] VALUE [low] 
    DPS [24] VALUE [both_work] 
    DPS [101] VALUE [True] 
    DPS [102] VALUE [False] 
    DPS [104] VALUE [vol_normal] 
    DPS [105] VALUE [english] 

Goto charge:
evice bf051cb1514f3d5555mzwp:
    DPS [2] VALUE [True] 
    DPS [3] VALUE [chargego] 
    DPS [4] VALUE [stop] 
    DPS [5] VALUE [goto_charge] 
    DPS [6] VALUE [53] 
    DPS [7] VALUE [94] 
    DPS [8] VALUE [97] 
    DPS [9] VALUE [100] 
    DPS [14] VALUE [normal] 
    DPS [15] VALUE [03302204147] 
    DPS [16] VALUE [150] 
    DPS [17] VALUE [16] 
    DPS [18] VALUE [0] 
    DPS [20] VALUE [low] 
    DPS [24] VALUE [both_work] 
    DPS [101] VALUE [True] 
    DPS [102] VALUE [False] 
    DPS [104] VALUE [vol_normal] 
    DPS [105] VALUE [english] 

So when adding to localtuya I'm selecting DPs:

2,3,4,5,6,7,8,9,14,15,16,17,18,20,24,101,102,104,105

And each of the mappings:

Idle status:
standby,sleep,stop

Power DP:
2
Docked Status:
charging,chargecompleted
Returning Status:
docking
Battery Status DP:
6
Mode DP:
3
Modes list:
smart,wall_follow,spiral,single
return home mode:
chargego
Fan speeds DP:
14
fan speeds list:
gentle,normal,strong
Clean time DP:
17
Clean area:
??
Clean Record dP:
15
Locate DP:
102?
Fault DP:
pause state:
paused
stop status:
standby

water control:
low,middle,high

work mode:
sweep&mop,mop,sweep

This is where I'm at so far, still some to correct and fix but I think it's almost there.

andyb2000 commented 5 months ago

One thing that is really sticking with me, is how to set the right value so it's not always cleaning! If it errors it shows that but it never shows docked/charging, it's always cleaning (e.g. right now it's docked/charging but it still shows cleaning):

image

silviudc commented 4 months ago

Let me know if you get this to work I have an Eufy robovac 15c max which does the same, if I don't give it the error DP it says cleaning the whole time if I do set the error DP it always says Error:

"0753038684f3ebf4b8d5": {
              "friendly_name": "Upstairs robovac",
              "host": "192.168.0.94",
              "local_key": "e850ab63ec1461ba",
              "protocol_version": "3.3",
              "enable_debug": false,
              "entities": [
                {
                  "friendly_name": "Upstairs robovac",
                  "idle_status_value": "standby,Sleeping",
                  "powergo_dp": 2,
                  "docked_status_value": "Charging,completed",
                  "returning_status_value": "docking",
                  "battery_dp": 104,
                  "mode_dp": 5,
                  "modes": "auto,SmallRoom,Spot,Edge,Nosweep",
                  "return_mode": "chargego",
                  "fan_speed_dp": 102,
                  "fan_speeds": "Standard,Boost_IQ,Max,No_suction",
                  "paused_state": "paused",
                  "stop_status": "standby",
                  "fault_dp": 106,
                  "id": 1,
                  "platform": "vacuum"
                }
              ],
              "add_entities": false,
              "device_id": "0753038684f3ebf4b8d5",
              "dps_strings": [
                "1 (value: True)",
                "2 (value: False)",
                "3 (value: left)",
                "5 (value: Nosweep)",
                "15 (value: standby)",
                "101 (value: False)",
                "102 (value: Boost_IQ)",
                "103 (value: False)",
                "104 (value: 76)",
                "106 (value: no_error)"
              ]
            }
andyb2000 commented 4 months ago

Hi there,

Good news is with a bit of testing I've got it sorted.

Here is how mine is now setup. I added the main section then added three extra sensors which allow me to query the battery level, cleaning time and error state (which allows easier automation, etc)

           "bf051cb1514f3d5555mzwp": {             
              "friendly_name": "Vac",            
              "host": "192.168.xx.x",             
              "local_key": "REDACT",      
              "protocol_version": "3.3",            
              "enable_debug": false,                
              "entities": [                            
                {                              
                  "friendly_name": "Vac",   
                  "idle_status_value": "standby,sleep,stop",
                  "powergo_dp": 2,                          
                  "docked_status_value": "charging,chargecompleted,charge_done",
                  "returning_status_value": "docking",                          
                  "battery_dp": 6,                                              
                  "mode_dp": 3,                                                 
                  "modes": "smart,wall_follow,spiral,single",                   
                  "return_mode": "chargego",                                    
                  "fan_speed_dp": 14,                                           
                  "fan_speeds": "gentle,normal,strong",                         
                  "clean_time_dp": 17,                                          
                  "clean_record_dp": 15,                                        
                  "locate_dp": 102,                                             
                  "fault_dp": 18,                                               
                  "paused_state": "paused",                                     
                  "stop_status": "standby",                  
                  "id": 5,                                   
                  "platform": "vacuum"                       
                },                                           
                {                                                               
                  "friendly_name": "Battery",                                   
                  "device_class": "battery",                                    
                  "id": 6,                                                      
                  "platform": "sensor"                                          
                },                                                              
                {                                                               
                  "friendly_name": "cleaning time",                             
                  "device_class": "duration",                                   
                  "id": 17,                                                     
                  "platform": "sensor"                                          
                },                                                              
                {                                                               
                  "id": 18,                                                     
                  "friendly_name": "Error Code",                                
                  "device_class": "enum",                                       
                  "platform": "sensor"                                          
                }                                                               
              ],                                                                
              "add_entities": true,                                             
              "model": "G20",                                                   
              "device_id": "bf051cb1514f3d5555mzwp",                            
              "dps_strings": [                                                  
                "2 (value: False)",                                             
                "3 (value: standby)",                                           
                "4 (value: stop)",                           
                "5 (value: charge_done)",                    
                "6 (value: 100)",                            
                "7 (value: 92)",                             
                "8 (value: 96)",                                                
                "9 (value: 100)",                                               
                "14 (value: normal)",                                           
                "15 (value: 05403404168)",                                      
                "16 (value: 0)",                                                
                "17 (value: 0)",                                                
                "18 (value: 0)",                                                
                "20 (value: low)",                                              
                "24 (value: both_work)",                                        
                "101 (value: True)",                                            
                "102 (value: False)",                                           
                "104 (value: vol_normal)",                                      
                "105 (value: english)"                                          
              ],                                                                
              "product_key": "rxmacvgkaz640r4q"                                 
            }                                                                   
          },                                                                    
          "updated_at": "1706526043374"                                         
        },                                                                      
        "options": {},                                                          
        "pref_disable_new_entities": false,                                     
        "pref_disable_polling": false,                                          
        "source": "user",                                                       
        "unique_id": "bfe3e7c4667eb339acih6l",                                  
        "disabled_by": null                                                     
      },                                                     
andyb2000 commented 2 weeks ago

Hi.

I'm unsure what is needed to get this added to localtuya, can anyone advise?

I see that it's discovered correctly in tinytuya, device output is:

(This is the output from tinytuya for my G20)

    {
        "name": "Albert",
        "id": "bf051cb1514f3d5555mxxx",
        "key": "Exxxxxxxxx",
        "mac": "18:de:50:e3:xx:xx",
        "uuid": "db8c2fb91xxxxxxx",
        "sn": "1001216xxxxxxx",
        "category": "sd",
        "product_name": "G20",
        "product_id": "rxmacvgkaz640r4q",
        "biz_type": 18,
        "model": "G20",
        "sub": false,
        "icon": "https://images.tuyaeu.com/smart/icon/bay1597905160549l20L/824e637609fad68a7de501be6064dc6f.png",
        "mapping": {
            "2": {
                "code": "power_go",
                "type": "Boolean",
                "values": {}
            },
            "3": {
                "code": "mode",
                "type": "Enum",
                "values": {
                    "range": [
                        "standby",
                        "smart",
                        "wall_follow",
                        "spiral",
                        "chargego",
                        "random"
                    ]
                }
            },
            "4": {
                "code": "direction_control",
                "type": "Enum",
                "values": {
                    "range": [
                        "forward",
                        "backward",
                        "turn_left",
                        "turn_right",
                        "stop"
                    ]
                }
            },
            "5": {
                "code": "status",
                "type": "Enum",
                "values": {
                    "range": [
                        "standby",
                        "cleaning",
                        "goto_charge",
                        "charging",
                        "charge_done",
                        "smart_clean",
                        "wall_clean",
                        "spot_clean",
                        "sleep"
                    ]
                }
            },
            "6": {
                "code": "electricity_left",
                "type": "Integer",
                "values": {
                    "unit": "%",
                    "min": 0,
                    "max": 100,
                    "scale": 0,
                    "step": 1
                }
            },
            "7": {
                "code": "edge_brush",
                "type": "Integer",
                "values": {
                    "unit": "%",
                    "min": 0,
                    "max": 100,
                    "scale": 0,
                    "step": 1
                }
            },
            "8": {
                "code": "roll_brush",
                "type": "Integer",
                "values": {
                    "unit": "%",
                    "min": 0,
                    "max": 100,
                    "scale": 0,
                    "step": 1
                }
            },
            "9": {
                "code": "filter",
                "type": "Integer",
                "values": {
                    "unit": "%",
                    "min": 0,
                    "max": 100,
                    "scale": 0,
                    "step": 1
                }
            },
            "10": {
                "code": "reset_edge_brush",
                "type": "Boolean",
                "values": {}
            },
            "11": {
                "code": "reset_roll_brush",
                "type": "Boolean",
                "values": {}
            },
            "12": {
                "code": "reset_filter",
                "type": "Boolean",
                "values": {}
            },
            "13": {
                "code": "seek",
                "type": "Boolean",
                "values": {}
            },
            "14": {
                "code": "suction",
                "type": "Enum",
                "values": {
                    "range": [
                        "gentle",
                        "normal",
                        "strong"
                    ]
                }
            },
            "15": {
                "code": "clean_record",
                "type": "String",
                "values": "{\"maxlen\":255}"
            },
            "16": {
                "code": "clean_area",
                "type": "Integer",
                "values": {
                    "unit": "\u33a1",
                    "min": 0,
                    "max": 9999,
                    "scale": 1,
                    "step": 1
                }
            },
            "17": {
                "code": "clean_time",
                "type": "Integer",
                "values": {
                    "unit": "min",
                    "min": 0,
                    "max": 9999,
                    "scale": 0,
                    "step": 1
                }
            },
            "18": {
                "code": "fault",
                "type": "Bitmap",
                "values": {
                    "label": [
                        "edge_sweep",
                        "middle_sweep",
                        "left_wheel",
                        "right_wheel",
                        "garbage_box",
                        "land_check",
                        "collision",
                        "give_up",
                        "low_power",
                        "fan",
                        "dwheel",
                        "uwheel"
                    ]
                }
            },
            "20": {
                "code": "cistern",
                "type": "Enum",
                "values": {
                    "range": [
                        "low",
                        "middle",
                        "high"
                    ]
                }
            },
            "105": {
                "code": "language",
                "type": "Enum",
                "values": {
                    "range": [
                        "english",
                        "german",
                        "french",
                        "italian",
                        "spanish",
                        "japanese"
                    ]
                }
            }
        },
        "ip": "192.168.XX.XX,
        "version": "3.4"
    },