make-all / tuya-local

Local support for Tuya devices in Home Assistant
MIT License
1.39k stars 535 forks source link

LuBlueLu SL60D Start Cleaning/Pause are misbehaving #2334

Closed reef-actor closed 1 month ago

reef-actor commented 1 month ago

When the vacuum is docked (status: sleep), the ▶️ button does not start cleaning. It does change the value of the Activate attribute to true. The ⏸️ button will reset Activate to false. I have not found a way to start cleaning using Tuya Local.

Starting cleaning using the app, I see the following attribute changes: Power: false -> true Command: return_to_base -> smart The "Activate" attribute stays false.

When cleaning has been started, the ▶️ button will change the vacuum to "status: paused". When the vacuum is "status: paused", the ⏸️ button will resume cleaning.

Expected behavior The ▶️ button will start or resume cleaning. The ⏸️ button will pause cleaning or returning to dock.

Device diagnostics ``` { "home_assistant": { "installation_type": "Unsupported Third Party Container", "version": "2024.9.2", "dev": false, "hassio": false, "virtualenv": false, "python_version": "3.12.4", "docker": true, "arch": "x86_64", "timezone": "Europe/London", "os_name": "Linux", "os_version": "6.1.0-25-amd64", "run_as_root": false }, "custom_components": { "tuya_cloud_map_extractor": { "documentation": "https://github.com/oven-lab/tuya_cloud_map_extractor/blob/main/README.md", "version": "v1.2.0", "requirements": [ "numpy", "pillow", "requests" ] }, "ingress": { "documentation": "https://github.com/lovelylain/hass_ingress", "version": "1.1.6", "requirements": [] }, "homewhiz": { "documentation": "https://github.com/home-assistant-HomeWhiz/home-assistant-HomeWhiz", "version": "0.0.6", "requirements": [ "awsiotsdk", "bleak", "bleak_retry_connector", "dacite", "aiohttp", "bidict" ] }, "watchman": { "documentation": "https://github.com/dummylabs/thewatchman", "version": "0.6.3", "requirements": [ "prettytable==3.10.0" ] }, "frigate": { "documentation": "https://github.com/blakeblackshear/frigate", "version": "5.4.0", "requirements": [ "pytz" ] }, "tuya_local": { "documentation": "https://github.com/make-all/tuya-local", "version": "2024.9.0", "requirements": [ "tinytuya==1.15.1", "tuya-device-sharing-sdk>=0.1.9,<=0.2.99" ] }, "hacs": { "documentation": "https://hacs.xyz/docs/configuration/start", "version": "2.0.1", "requirements": [ "aiogithubapi>=22.10.1" ] }, "elkbledom": { "documentation": "https://github.com/dave-code-ruiz/elkbledom", "version": "1.0.2", "requirements": [ "bleak-retry-connector>=1.17.1", "bleak>=0.17.0" ] }, "localtuya": { "documentation": "https://github.com/rospogrigio/localtuya/", "version": "5.2.1", "requirements": [] } }, "integration_manifest": { "domain": "tuya_local", "name": "Tuya Local", "codeowners": [ "make-all" ], "config_flow": true, "dependencies": [], "documentation": "https://github.com/make-all/tuya-local", "integration_type": "device", "iot_class": "local_push", "issue_tracker": "https://github.com/make-all/tuya-local/issues", "requirements": [ "tinytuya==1.15.1", "tuya-device-sharing-sdk>=0.1.9,<=0.2.99" ], "version": "2024.9.0", "is_built_in": false }, "setup_times": { "null": { "setup": 3.7493009585887194e-05 }, "4b2cdc49720b1c7452f49e793ea524f3": { "wait_import_platforms": -2.048404594010208, "wait_base_component": -0.001281788048800081, "config_entry_setup": 2.158301817951724 } }, "data": { "name": "Robot vacuum", "type": "lublueblu_sl60d_vacuum", "device_id": "**REDACTED**", "device_cid": "", "local_key": "**REDACTED**", "host": "**REDACTED**", "protocol_version": 3.3, "tinytuya_version": "1.15.1", "api_version_set": 3.3, "api_version_used": 3.3, "api_working": true, "status": {}, "cached_state": { "updated_at": 1727359800.2520025, "1": false, "2": true, "3": true, "4": "smart", "5": "charge_done", "6": 0, "7": 0, "8": 100, "9": "normal", "10": "middle", "11": true, "12": "stop", "16": "get_both", "17": 79, "19": 229, "21": 79, "25": false, "26": 33, "27": false, "28": 0, "29": 4484, "30": 182, "31": 4068, "37": 1, "39": false, "40": "none", "41": "only_sweep", "44": "adaptive", "45": true, "15": "qgADFQEAFqoAARcXqgADKQEAKg==" }, "pending_state": {}, "connected": true, "force_dps": [], "home_assistant": { "name": "Robot vacuum", "name_by_user": null, "disabled": false, "disabled_by": null, "entities": [ { "disabled": false, "disabled_by": null, "entity_category": null, "device_class": null, "original_device_class": null, "icon": null, "unit_of_measurement": null, "state": { "entity_id": "vacuum.robot_vacuum", "state": "idle", "attributes": { "fan_speed_list": [ "Low", "Medium", "High" ], "fan_speed": "Medium", "power": false, "activate": true, "charge": true, "command": "smart", "status": "sleep", "locate": true, "direction_control": "stop", "break_clean": false, "error": 0, "friendly_name": "Robot vacuum", "supported_features": 14263 }, "last_changed": "2024-09-26T14:08:25.499247+00:00", "last_reported": "2024-09-26T14:09:28.513366+00:00", "last_updated": "2024-09-26T14:08:25.499247+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "diagnostic", "device_class": null, "original_device_class": "duration", "icon": null, "unit_of_measurement": "min", "state": { "entity_id": "sensor.robot_vacuum_cleaning_time", "state": "0", "attributes": { "unit_of_measurement": "min", "device_class": "duration", "icon": "mdi:progress-clock", "friendly_name": "Robot vacuum Cleaning time" }, "last_changed": "2024-09-26T12:58:26.419585+00:00", "last_reported": "2024-09-26T14:09:28.514944+00:00", "last_updated": "2024-09-26T12:58:26.419585+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "diagnostic", "device_class": null, "original_device_class": null, "icon": null, "unit_of_measurement": "m\u00b2", "state": { "entity_id": "sensor.robot_vacuum_cleaning_area", "state": "0", "attributes": { "unit_of_measurement": "m\u00b2", "icon": "mdi:floor-plan", "friendly_name": "Robot vacuum Cleaning area" }, "last_changed": "2024-09-26T12:58:26.420260+00:00", "last_reported": "2024-09-26T14:09:28.515263+00:00", "last_updated": "2024-09-26T12:58:26.420260+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": null, "device_class": null, "original_device_class": "battery", "icon": null, "unit_of_measurement": "%", "state": { "entity_id": "sensor.robot_vacuum_battery", "state": "100", "attributes": { "state_class": "measurement", "unit_of_measurement": "%", "device_class": "battery", "friendly_name": "Robot vacuum Battery" }, "last_changed": "2024-09-26T12:50:49.004552+00:00", "last_reported": "2024-09-26T14:09:28.515605+00:00", "last_updated": "2024-09-26T12:50:49.004552+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "diagnostic", "device_class": null, "original_device_class": "enum", "icon": null, "unit_of_measurement": null, "state": { "entity_id": "sensor.robot_vacuum_water_tank", "state": "unavailable", "attributes": { "restored": true, "options": [ "Closed", "Low", "Medium", "High" ], "device_class": "enum", "icon": "mdi:cup-water", "friendly_name": "Water tank", "supported_features": 0 }, "last_changed": "2024-09-26T12:51:26.076369+00:00", "last_reported": "2024-09-26T12:51:26.076369+00:00", "last_updated": "2024-09-26T12:51:26.076369+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "diagnostic", "device_class": null, "original_device_class": "duration", "icon": null, "unit_of_measurement": "h", "state": { "entity_id": "sensor.robot_vacuum_side_brush_lifetime", "state": "79", "attributes": { "unit_of_measurement": "h", "device_class": "duration", "friendly_name": "Robot vacuum Side brush lifetime" }, "last_changed": "2024-09-26T12:50:49.005203+00:00", "last_reported": "2024-09-26T14:09:28.515945+00:00", "last_updated": "2024-09-26T12:50:49.005203+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "diagnostic", "device_class": null, "original_device_class": "duration", "icon": null, "unit_of_measurement": "h", "state": { "entity_id": "sensor.robot_vacuum_rolling_brush_lifetime", "state": "229", "attributes": { "unit_of_measurement": "h", "device_class": "duration", "friendly_name": "Robot vacuum Rolling brush lifetime" }, "last_changed": "2024-09-26T12:50:49.006546+00:00", "last_reported": "2024-09-26T14:09:28.516265+00:00", "last_updated": "2024-09-26T12:50:49.006546+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "diagnostic", "device_class": null, "original_device_class": "duration", "icon": null, "unit_of_measurement": "h", "state": { "entity_id": "sensor.robot_vacuum_filter_lifetime", "state": "79", "attributes": { "unit_of_measurement": "h", "device_class": "duration", "friendly_name": "Robot vacuum Filter lifetime" }, "last_changed": "2024-09-26T12:50:49.006749+00:00", "last_reported": "2024-09-26T14:09:28.516587+00:00", "last_updated": "2024-09-26T12:50:49.006749+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "diagnostic", "device_class": null, "original_device_class": "duration", "icon": null, "unit_of_measurement": "min", "state": { "entity_id": "sensor.robot_vacuum_duster_cloth_lifetime", "state": "unknown", "attributes": { "unit_of_measurement": "min", "device_class": "duration", "friendly_name": "Robot vacuum Duster cloth lifetime" }, "last_changed": "2024-09-26T12:50:49.006897+00:00", "last_reported": "2024-09-26T14:09:28.516947+00:00", "last_updated": "2024-09-26T12:50:49.006897+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "diagnostic", "device_class": null, "original_device_class": null, "icon": null, "unit_of_measurement": "m\u00b2", "state": { "entity_id": "sensor.robot_vacuum_total_cleaning_area", "state": "4484", "attributes": { "unit_of_measurement": "m\u00b2", "icon": "mdi:texture-box", "friendly_name": "Robot vacuum Total cleaning area" }, "last_changed": "2024-09-26T12:50:49.007050+00:00", "last_reported": "2024-09-26T14:09:28.517334+00:00", "last_updated": "2024-09-26T12:50:49.007050+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "diagnostic", "device_class": null, "original_device_class": null, "icon": null, "unit_of_measurement": null, "state": { "entity_id": "sensor.robot_vacuum_total_cleaning_times", "state": "182", "attributes": { "icon": "mdi:counter", "friendly_name": "Robot vacuum Total cleaning times" }, "last_changed": "2024-09-26T12:50:49.007193+00:00", "last_reported": "2024-09-26T14:09:28.517695+00:00", "last_updated": "2024-09-26T12:50:49.007193+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "diagnostic", "device_class": null, "original_device_class": "duration", "icon": null, "unit_of_measurement": "min", "state": { "entity_id": "sensor.robot_vacuum_total_cleaning_time", "state": "4068", "attributes": { "unit_of_measurement": "min", "device_class": "duration", "icon": "mdi:history", "friendly_name": "Robot vacuum Total cleaning time" }, "last_changed": "2024-09-26T12:50:49.007392+00:00", "last_reported": "2024-09-26T14:09:28.518024+00:00", "last_updated": "2024-09-26T12:50:49.007392+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "config", "device_class": null, "original_device_class": null, "icon": null, "unit_of_measurement": null, "state": { "entity_id": "switch.robot_vacuum_do_not_disturb_2", "state": "off", "attributes": { "icon": "mdi:minus-circle", "friendly_name": "Robot vacuum Do not disturb" }, "last_changed": "2024-09-26T12:50:49.003966+00:00", "last_reported": "2024-09-26T14:09:28.514539+00:00", "last_updated": "2024-09-26T12:50:49.003966+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "config", "device_class": null, "original_device_class": null, "icon": null, "unit_of_measurement": null, "state": { "entity_id": "button.robot_vacuum_reset_map", "state": "unknown", "attributes": { "icon": "mdi:map-marker-remove", "friendly_name": "Robot vacuum Reset map" }, "last_changed": "2024-09-26T12:50:49.003499+00:00", "last_reported": "2024-09-26T12:50:49.003499+00:00", "last_updated": "2024-09-26T12:50:49.003499+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "config", "device_class": null, "original_device_class": "restart", "icon": null, "unit_of_measurement": null, "state": { "entity_id": "button.robot_vacuum_reset_edge_brush", "state": "unknown", "attributes": { "device_class": "restart", "friendly_name": "Robot vacuum Reset edge brush" }, "last_changed": "2024-09-26T12:50:49.003609+00:00", "last_reported": "2024-09-26T12:50:49.003609+00:00", "last_updated": "2024-09-26T12:50:49.003609+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "config", "device_class": null, "original_device_class": "restart", "icon": null, "unit_of_measurement": null, "state": { "entity_id": "button.robot_vacuum_reset_roll_brush", "state": "unknown", "attributes": { "device_class": "restart", "friendly_name": "Robot vacuum Reset roll brush" }, "last_changed": "2024-09-26T12:50:49.003707+00:00", "last_reported": "2024-09-26T12:50:49.003707+00:00", "last_updated": "2024-09-26T12:50:49.003707+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "config", "device_class": null, "original_device_class": null, "icon": null, "unit_of_measurement": null, "state": { "entity_id": "button.robot_vacuum_reset_filter", "state": "unknown", "attributes": { "icon": "mdi:air-filter", "friendly_name": "Robot vacuum Reset filter" }, "last_changed": "2024-09-26T12:50:49.003813+00:00", "last_reported": "2024-09-26T12:50:49.003813+00:00", "last_updated": "2024-09-26T12:50:49.003813+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "config", "device_class": null, "original_device_class": null, "icon": null, "unit_of_measurement": "%", "state": { "entity_id": "number.robot_vacuum_volume", "state": "33", "attributes": { "min": 0.0, "max": 100.0, "step": 1.0, "mode": "auto", "unit_of_measurement": "%", "icon": "mdi:volume-high", "friendly_name": "Robot vacuum Volume" }, "last_changed": "2024-09-26T12:50:49.002347+00:00", "last_reported": "2024-09-26T14:09:28.510436+00:00", "last_updated": "2024-09-26T12:50:49.002347+00:00" } }, { "disabled": false, "disabled_by": null, "entity_category": "config", "device_class": null, "original_device_class": null, "icon": null, "unit_of_measurement": null, "state": { "entity_id": "select.robot_vacuum_water_tank", "state": "Medium", "attributes": { "options": [ "Closed", "Low", "Medium", "High" ], "icon": "mdi:cup-water", "friendly_name": "Robot vacuum Water tank" }, "last_changed": "2024-09-26T12:50:49.002100+00:00", "last_reported": "2024-09-26T14:09:28.509876+00:00", "last_updated": "2024-09-26T12:50:49.002100+00:00" } } ] } } } ```
make-all commented 1 month ago

It isn't clear what needs to be done here. The initial config was submitted as a PR, so the initial information that is used to create configs is not available. There have been a couple of bug reports in the past about device detection that suggest the initial integration was not well tested, but without more info about the device anything I could do here would be just blind experimentation.

reef-actor commented 1 month ago

If there is any diagnostics/logs that might contain clues I can have a dig through them. Can you explain what effect the change to the "power" entry in this commit had? I suspect this issue is due to Power and Activate being mixed up, perhaps the device is dealing with them in a funky way.

I had assumed this vacuum didn't support this, but on a whim I tried localtuya and was able to start cleaning (ironically this was the only function that worked out of the box with that integration). I am trying to understand what that code is doing differently but I don't regularly deal with python so it will take a bit of effort to understand how it maps DPs.

make-all commented 1 month ago

It is more the tuya developer portal info for the device that will help. ie, the QueryThingsDataModel cloud API call result. That will show what names Tuya has given to the dps, and maybe include Chinese language descriptions that explain a bit more how they are used.

The commit you highlight just makes those two dps optional, as previous reports showed they weren't always reported by the device. The power dp has a default of off added, because if the power is missing HA makes the whole entity unavailable and you cannot use it.

What you are saying sounds familiar, so probably one of the other vacuums has already been changed to deal with this same issue.

reef-actor commented 1 month ago
QueryThingsDataModel result ``` { "modelId": "elkmg4", "services": [ { "actions": [], "code": "", "description": "", "events": [], "name": "默认服务", "properties": [ { "abilityId": 1, "accessMode": "rw", "code": "switch_go", "description": "true:清扫启动\nfalse:清扫停止", "extensions": { "iconName": "icon-power", "attribute": "672" }, "name": "清扫开关", "typeSpec": { "type": "bool" } }, { "abilityId": 2, "accessMode": "rw", "code": "pause", "description": "true:暂停当前工作状态\nfalse:继续当前工作状态", "extensions": { "iconName": "icon-dp_pause", "attribute": "672" }, "name": "暂停/继续", "typeSpec": { "type": "bool" } }, { "abilityId": 3, "accessMode": "rw", "code": "switch_charge", "description": "true:回充启动\nfalse:回充停止", "extensions": { "iconName": "icon-a_power", "attribute": "160" }, "name": "回充开关", "typeSpec": { "type": "bool" } }, { "abilityId": 4, "accessMode": "rw", "code": "mode", "description": "默认值(不可修改删除,否则影响控制面板逻辑):\nsmart - 自动清扫模式/全屋清扫模式 \nchargego - 自动回充模式(需要兼容:goto_charge)\nzone - 划区清扫模式/矩形清扫模式\npose - 指哪扫哪模式/定点清扫模式\npart - 局部清扫模式\nselect_room - 选区清扫模式", "extensions": { "iconName": "icon-dp_mode", "attribute": "704" }, "name": "工作模式", "typeSpec": { "type": "enum", "range": [ "smart", "chargego", "zone", "pose", "part", "selectroom" ] } }, { "abilityId": 5, "accessMode": "ro", "code": "status", "description": "默认值(不可修改删除,否则影响控制面板逻辑):\nstandby - 待机中\nsmart - 自动清扫中 \nzone_clean - 划区清扫中\npart_clean - 局部清扫中\ncleaning - 清扫中(备选) \npaused - 已暂停\ngoto_pos - 前往目标点中\npos_arrived - 目标点已到达 \npos_unarrive - 目标点不可达 \ngoto_charge - 寻找充电座中 \ncharging - 充电中\ncharge_done - 充电完成 \nsleep - 休眠\nselect_room - 选区清扫中\n\n可在后面增加其他状态值,状态值尽量是状态的英文小写单词,如需要增加故障中状态,则为in_trouble", "extensions": { "iconName": "icon-zhuangtai", "attribute": "706" }, "name": "机器状态:", "typeSpec": { "type": "enum", "range": [ "standby", "smart", "zone_clean", "part_clean", "cleaning", "paused", "goto_pos", "pos_arrived", "pos_unarrive", "goto_charge", "charging", "charge_done", "sleep", "select_room" ] } }, { "abilityId": 6, "accessMode": "ro", "code": "clean_time", "description": "默认区间为0min—9999分钟(没有小数点),如果需要显示为小数点,可以修改倍数参数,例如需要支持一位小数点,则倍数参数为1,上报的数值会经过计算,保留一位小数,例如上报589,经过换算后为58.9min", "extensions": { "iconName": "icon-dp_time3", "attribute": "192" }, "name": "清扫时间", "typeSpec": { "type": "value", "max": 9999, "min": 0, "scale": 0, "step": 1, "unit": "min" } }, { "abilityId": 7, "accessMode": "ro", "code": "clean_area", "description": "默认区间为0㎡—9999㎡(没有小数点),如果需要显示为小数点,可以修改倍数参数,例如需要支持一位小数点,则倍数参数为1,上报的数值会经过计算,保留一位小数,例如上报589,经过换算后为58.9㎡", "extensions": { "iconName": "icon-icon-test10", "attribute": "192" }, "name": "清扫面积", "typeSpec": { "type": "value", "max": 9999, "min": 0, "scale": 0, "step": 1, "unit": "㎡" } }, { "abilityId": 8, "accessMode": "ro", "code": "battery_percentage", "description": "默认区间为0%—100%(没有小数点),如果需要显示为小数点,可以修改倍数参数,例如需要支持一位小数点,则倍数参数为1,上报的数值会经过计算,保留一位小数,例如上报589,经过换算后为58.9%", "extensions": { "iconName": "icon-dp_battery", "attribute": "194" }, "name": "剩余电量", "typeSpec": { "type": "value", "max": 100, "min": 0, "scale": 0, "step": 1, "unit": "%" } }, { "abilityId": 9, "accessMode": "rw", "code": "suction", "description": "默认值(可修改、删除、增加):\n\ngentle - 安静\nnormal - 正常\nstrong - 强劲\nsuper_strong-超强\n\n选项排列与此处值的排列顺序一致,可调整排列顺序,可删减值,可增加其他状态值,状态值尽量是状态的英文小写单词,如需要增加自动状态,则为auto", "extensions": { "iconName": "icon-Strong", "attribute": "128" }, "name": "吸力选择", "typeSpec": { "type": "enum", "range": [ "gentle", "normal", "strong" ] } }, { "abilityId": 10, "accessMode": "rw", "code": "cistern", "description": "默认值(可修改、删除、增加):\nclosed-关闭\nlow - 低\nmiddle - 中\nhigh - 高\n\n选项排列与此处值的排列顺序一致,可调整排列顺序,可删减值,可增加其他状态值,状态值尽量是状态的英文小写单词,如需要增加自动状态,则为auto", "extensions": { "iconName": "icon-dp_water", "attribute": "128" }, "name": "水量选择", "typeSpec": { "type": "enum", "range": [ "closed", "low", "middle", "high" ] } }, { "abilityId": 11, "accessMode": "rw", "code": "seek", "description": "", "extensions": { "iconName": "icon-dp_magnifier", "attribute": "128" }, "name": "寻找机器", "typeSpec": { "type": "bool" } }, { "abilityId": 12, "accessMode": "rw", "code": "direction_control", "description": "默认值(不可修改、删除、增加),按键按下下发对应的方向值,松手下发停", "extensions": { "iconName": "icon-dp_compass", "attribute": "224" }, "name": "清扫方向", "typeSpec": { "type": "enum", "range": [ "forward", "backward", "turn_left", "turn_right", "stop" ] } }, { "abilityId": 13, "accessMode": "rw", "code": "map_reset", "description": "", "extensions": { "iconName": "icon-dp_loop", "attribute": "128" }, "name": "重置地图", "typeSpec": { "type": "bool" } }, { "abilityId": 14, "accessMode": "rw", "code": "path_data", "description": "相关数据协议及逻辑可参看开发包中激光扫地机地图协议文件", "extensions": { "iconName": "icon-dp_fly", "attribute": "736" }, "name": "路径传输", "typeSpec": { "type": "raw", "maxlen": 128 } }, { "abilityId": 15, "accessMode": "rw", "code": "command_trans", "description": "相关数据协议及逻辑可参看开发包中激光扫地机地图协议文件", "extensions": { "iconName": "icon-dp_fly", "attribute": "736" }, "name": "指令传输", "typeSpec": { "type": "raw", "maxlen": 128 } }, { "abilityId": 16, "accessMode": "rw", "code": "request", "description": "相关数据协议及逻辑可参看开发包中激光扫地机地图协议文件", "extensions": { "iconName": "icon-dp_mode", "attribute": "736" }, "name": "请求数据", "typeSpec": { "type": "enum", "range": [ "get_map", "get_path", "get_both" ] } }, { "abilityId": 17, "accessMode": "rw", "code": "edge_brush_life", "description": "默认区间为0hour—150hour(不支持小数点)\n注意:选择了该DP点,必须选择对应的重置DP点", "extensions": { "iconName": "icon-icon-percent", "attribute": "192" }, "name": "边刷剩余寿命", "typeSpec": { "type": "value", "max": 150, "min": 0, "scale": 0, "step": 1, "unit": "hour" } }, { "abilityId": 18, "accessMode": "rw", "code": "edge_brush_life_reset", "description": "", "extensions": { "iconName": "icon-dp_loop", "attribute": "160" }, "name": "边刷重置", "typeSpec": { "type": "bool" } }, { "abilityId": 19, "accessMode": "rw", "code": "roll_brush_life", "description": "默认区间为0hour—300hour(不支持小数点)\n注意:选择了该DP点,必须选择对应的重置DP点", "extensions": { "iconName": "icon-icon-percent", "attribute": "192" }, "name": "滚刷剩余寿命", "typeSpec": { "type": "value", "max": 300, "min": 0, "scale": 0, "step": 1, "unit": "hour" } }, { "abilityId": 20, "accessMode": "rw", "code": "roll_brush_life_reset", "description": "", "extensions": { "iconName": "icon-dp_loop", "attribute": "160" }, "name": "滚刷重置", "typeSpec": { "type": "bool" } }, { "abilityId": 21, "accessMode": "ro", "code": "filter_life", "description": "默认区间为0hour—150hour(不支持小数点)\n注意:选择了该DP点,必须选择对应的重置DP点", "extensions": { "iconName": "icon-dp_time2", "attribute": "192" }, "name": "海帕剩余寿命", "typeSpec": { "type": "value", "max": 150, "min": 0, "scale": 0, "step": 1, "unit": "hour" } }, { "abilityId": 22, "accessMode": "rw", "code": "filter_reset", "description": "", "extensions": { "iconName": "icon-dp_loop", "attribute": "160" }, "name": "海帕重置", "typeSpec": { "type": "bool" } }, { "abilityId": 23, "accessMode": "ro", "code": "rag_life", "description": "默认区间为0min—9000min(不支持小数点)\n注意:选择了该DP点,必须选择对应的重置DP点", "extensions": { "iconName": "icon-icon-percent", "attribute": "1216" }, "name": "拖布剩余寿命", "typeSpec": { "type": "value", "max": 9000, "min": 0, "scale": 0, "step": 1, "unit": "min" } }, { "abilityId": 25, "accessMode": "rw", "code": "do_not_disturb", "description": "", "extensions": { "iconName": "icon-dp_mode", "attribute": "128" }, "name": "勿扰开关", "typeSpec": { "type": "bool" } }, { "abilityId": 26, "accessMode": "rw", "code": "volume_set", "description": "默认区间为0—100,可自行修改区间,不支持小数点", "extensions": { "iconName": "icon-dp_voice", "attribute": "128" }, "name": "音量设置", "typeSpec": { "type": "value", "max": 100, "min": 0, "scale": 0, "step": 1, "unit": "%" } }, { "abilityId": 27, "accessMode": "rw", "code": "break_clean", "description": "", "extensions": { "iconName": "icon-dp_wash", "attribute": "128" }, "name": "断点续扫", "typeSpec": { "type": "bool" } }, { "abilityId": 28, "accessMode": "rw", "code": "fault", "description": "默认值(不可修改删除,否则影响控制面板逻辑):\nedge_sweep_fault - 边刷故障\nmiddle_sweep_fault - 滚刷故障\nleft_wheel_fault - 左轮故障\nright_wheel_fault - 右轮故障\ngarbage_box_fault - 尘盒故障\nland_check_fault - 地检故障\ncollision_fault - 碰撞传感器故障\n\n可在后面增加其他状态值,状态值尽量是状态的英文小写单词,如需要增加故障中状态,则为in_trouble", "extensions": { "iconName": "icon-baojing", "scope": "fault", "attribute": "704" }, "name": "故障上报", "typeSpec": { "type": "bitmap", "label": [ "edge_sweep", "middle_sweep", "left_wheel", "right_wheel", "garbage_box", "land_check", "collision", "e1", "e2", "e3", "e4", "e5", "e6", "e7", "e8", "e9", "e10", "e11", "e12", "e13", "e14", "e15", "e16", "e17", "e18", "e19", "e20", "e21", "e22", "e23" ], "maxlen": 30 } }, { "abilityId": 29, "accessMode": "ro", "code": "clean_area_total", "description": "默认区间为0㎡—99999㎡(没有小数点),如果需要显示为小数点,可以修改倍数参数,例如需要支持一位小数点,则倍数参数为1,上报的数值会经过计算,保留一位小数,例如上报589,经过换算后为58.9㎡", "extensions": { "iconName": "icon-tongji2", "attribute": "192" }, "name": "总清扫面积", "typeSpec": { "type": "value", "max": 99999, "min": 0, "scale": 0, "step": 1, "unit": "㎡" } }, { "abilityId": 30, "accessMode": "ro", "code": "clean_count_total", "description": "默认区间为0—99999(没有小数点),如果需要显示为小数点,可以修改倍数参数,例如需要支持一位小数点,则倍数参数为1,上报的数值会经过计算,保留一位小数,例如上报589,经过换算后为58.9", "extensions": { "iconName": "icon-tongji2", "attribute": "192" }, "name": "总清扫次数", "typeSpec": { "type": "value", "max": 99999, "min": 0, "scale": 0, "step": 1 } }, { "abilityId": 31, "accessMode": "ro", "code": "clean_time_total", "description": "默认区间为0min—99999min(没有小数点),如果需要显示为小数点,可以修改倍数参数,例如需要支持一位小数点,则倍数参数为1,上报的数值会经过计算,保留一位小数,例如上报589,经过换算后为58.9.min", "extensions": { "iconName": "icon-dp_time3", "attribute": "192" }, "name": "总清扫时间", "typeSpec": { "type": "value", "max": 99999, "min": 0, "scale": 0, "step": 1, "unit": "min" } }, { "abilityId": 32, "accessMode": "rw", "code": "device_timer", "description": "相关数据协议及逻辑可参看协议文件", "extensions": { "iconName": "icon-dp_time2", "attribute": "224" }, "name": "定时", "typeSpec": { "type": "raw", "maxlen": 128 } }, { "abilityId": 33, "accessMode": "rw", "code": "disturb_time_set", "description": "相关数据协议及逻辑可参看开发包中激光扫地机地图协议文件", "extensions": { "iconName": "icon-dp_time3", "attribute": "224" }, "name": "勿扰时间设置", "typeSpec": { "type": "raw", "maxlen": 128 } }, { "abilityId": 34, "accessMode": "ro", "code": "device_info", "description": "相关数据协议及逻辑可参看开发包中激光扫地机地图协议文件\n", "extensions": { "iconName": "icon-dp_mode", "attribute": "224" }, "name": "设备信息", "typeSpec": { "type": "raw", "maxlen": 128 } }, { "abilityId": 35, "accessMode": "rw", "code": "voice_data", "description": "配合DP36使用,相关数据协议及逻辑可参看开发包中激光扫地机地图协议文件\n", "extensions": { "iconName": "icon-dp_mode", "attribute": "224" }, "name": "语音包数据下发", "typeSpec": { "type": "raw", "maxlen": 128 } }, { "abilityId": 36, "accessMode": "rw", "code": "language", "description": "配合DP35使用,相关数据协议及逻辑可参看开发包中激光扫地机地图协议文件\n", "extensions": { "iconName": "icon-dp_mode", "attribute": "224" }, "name": "语音选择", "typeSpec": { "type": "enum", "range": [ "chinese_simplified", "chinese_traditional", "english", "german", "french", "russian", "spanish", "korean", "latin", "portuguese", "japanese", "italian" ] } }, { "abilityId": 37, "accessMode": "rw", "code": "dust_collection_num", "description": "默认区间为0—99999(没有小数点),该功能不支持小数点", "extensions": { "iconName": "icon-dp_wash", "attribute": "1216" }, "name": "集尘频率设置", "typeSpec": { "type": "value", "max": 4, "min": 0, "scale": 0, "step": 1 } }, { "abilityId": 38, "accessMode": "rw", "code": "dust_collection_switch", "description": "点击立即集尘,下发true", "extensions": { "iconName": "icon-dp_power2", "attribute": "160" }, "name": "集尘宝", "typeSpec": { "type": "bool" } }, { "abilityId": 39, "accessMode": "rw", "code": "customize_mode_switch", "description": "用于设置是否需要使用自定义的房间模式进行工作,如果需要使用自定义模式,则需要打开该开关", "extensions": { "iconName": "icon-dp_power2", "attribute": "128" }, "name": "自定义模式", "typeSpec": { "type": "bool" } }, { "abilityId": 40, "accessMode": "ro", "code": "mop_state", "description": "", "name": "拖布状态", "typeSpec": { "type": "enum", "range": [ "none", "installed" ] } }, { "abilityId": 41, "accessMode": "rw", "code": "work_mode", "description": "", "name": "工作模式", "typeSpec": { "type": "enum", "range": [ "both_work", "only_sweep", "only_mop" ] } }, { "abilityId": 44, "accessMode": "rw", "code": "carpet_clean_prefer", "description": "默认值(不可修改删除,否则影响控制面板逻辑):\nadaptive - 自适应\nevade - 规避\nignore - 忽略\n\n可在后面增加其他状态值,状态值尽量是状态的英文小写单词,如需要增加故障中状态,则为in_trouble", "extensions": { "iconName": "icon-dp_mode" }, "name": "清扫模式", "typeSpec": { "type": "enum", "range": [ "adaptive", "evade" ] } }, { "abilityId": 45, "accessMode": "rw", "code": "auto_boost", "description": "", "extensions": { "iconName": "icon-dp_up" }, "name": "地毯增压", "typeSpec": { "type": "bool" } } ] } ] } ```

From the API:

{
    "abilityId": 2,
    "accessMode": "rw",
    "code": "pause",
    "description": "true:暂停当前工作状态\nfalse:继续当前工作状态",
    "extensions": {
        "iconName": "icon-dp_pause",
        "attribute": "672"
    },
    "name": "暂停/继续",
    "typeSpec": {
        "type": "bool"
    }
}

In the YAML

    - id: 2
      type: boolean
      name: activate
      optional: true

I'm not 100% on how to interpret this, but that looks suspect?

make-all commented 1 month ago

Yes, when the dps are labelled switch_go and pause, they cannot be mapped directly to power and activate like that. Pause has the logic reversed, and switch_go is not the same as power. Those dps work more like buttons than switches.

reef-actor commented 1 month ago

I added support getting maps for this vacuum (from the cloud) to the tuya_cloud_map_extractor and think it would be cool if it could be done locally. DP 16 looks promising, but my concern is the disruption on this codebase caused by bringing all the parsing and decompressing functions over here. @make-all what do you think? Would it be worth me having a go to see how it turns out?

make-all commented 1 month ago

It may be worth adding the compression and decoding to the camera platform within tuya_local.

reef-actor commented 1 month ago

I appreciate your work here. It is ✨sometimes✨ working now. There seems to be a sequence of the pause, clean spot, locate and return to base commands that are needed, followed by one or several pushes of the start button to start it up. I will try and pin down a reproducible way start the cleaning.

Update: It seems that it is just necessary to keep trying Start until it works. Sometimes it works on the first attempt, sometimes it takes quite a few attempts.