CodeFoodPixels / robovac

Add a Eufy RoboVac easily to Home Assistant
Other
129 stars 28 forks source link

Commands don't necessarily work across different devices #28

Open CodeFoodPixels opened 1 year ago

CodeFoodPixels commented 1 year ago

Tried out beta 4, sadly still the same. Can add account and vacuum is auto discovered correctly but device remains unavailable with attribute error reported as “unknown” and no errors reported in the logs. Debug logging remains the same as my previous post. Also tried manually setting IP (auto discovery already had correct IP) but still the same.

Thanks so much for your perseverance it really is appreciated, please do let me know if there is anything I can try out on my end to help you understand where it’s having troubles.

My very limited trials with local Tuya was managing to connect however there was hardly any functionality (no way to start/stop a clean and so on) and the reported dps items were only the ones that are in the debug log which I have managed to figure out some of:

151: 156: Auto-Return Cleaning 158: Fan Speed (quiet,standard,turbo,max) 159: Boost IQ 160: 161: Voice Level 163: Battery Status

For the above I was able to successfully control the ones that can be via local Tuya and the changes were reflected on the robot and in Eufy app. Also updates were reflected in the integration on status updates or changes made via the Eufy app.

Originally posted by @john500y2k in https://github.com/CodeFoodPixels/robovac/issues/4#issuecomment-1709876655

I've discovered that the Tuya api that is being used to get the list of devices also returns a schema with the command codes. We could potentially use this to determine what commands we need to use

john500y2k commented 10 months ago

I've discovered that the Tuya api that is being used to get the list of devices also returns a schema with the command codes. We could potentially use this to determine what commands we need to use

Not sure what value this may be, but while searching through GitHub came across this repository which is for Homey but uses the TuyaAPI v4 and also seems to have integrated the X9 pro model looking through the release notes.

https://github.com/martijnpoppen/com.eufylife.home

I also formatted the previous DPS outputs from the other thread into a friendlier format:

Found device in tuya RoboVac X9 Pro [ { "attr": 0, "canTrigger": true, "code": "proto", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 150, "mode": "rw", "name": "协议", "property": { "type": "string", "maxlen": 255 }, "type": "obj" }, { "attr": 0, "canTrigger": true, "code": "power", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 151, "mode": "rw", "name": "电源开关", "property": { "type": "bool" }, "type": "obj" }, { "attr": 0, "canTrigger": true, "code": "mode_ctrl", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 152, "mode": "rw", "name": "模式控制", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "work_status", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 153, "mode": "rw", "name": "工作状态", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "clean_params", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 154, "mode": "rw", "name": "清洁参数", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "remote_ctrl", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 155, "mode": "rw", "name": "遥控方向", "property": { "range": [ "Brake", "Forward", "Back", "Left", "Right" ], "type": "enum" }, "type": "obj" }, { "attr": 0, "canTrigger": true, "code": "pause_job", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 156, "mode": "rw", "name": "断点续扫", "property": { "type": "bool" }, "type": "obj" }, { "attr": 0, "canTrigger": true, "code": "dnd", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 157, "mode": "rw", "name": "勿扰", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "suction_level", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 158, "mode": "rw", "name": "吸力档位", "property": { "range": [ "Quiet", "Standard", "Turbo", "Max" ], "type": "enum" }, "type": "obj" }, { "attr": 0, "canTrigger": true, "code": "boost_iq", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 159, "mode": "rw", "name": "BoostIQ", "property": { "type": "bool" }, "type": "obj" }, { "attr": 0, "canTrigger": true, "code": "calling_robot", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 160, "mode": "rw", "name": "寻找机器人", "property": { "type": "bool" }, "type": "obj" }, { "attr": 0, "canTrigger": true, "code": "volume", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 161, "mode": "rw", "name": "音量", "property": { "unit": "", "min": 0, "max": 100, "scale": 0, "step": 1, "type": "value" }, "type": "obj" }, { "attr": 0, "canTrigger": true, "code": "user_language", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 162, "mode": "rw", "name": "语言管理", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "bat_level", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 163, "mode": "ro", "name": "电池电量", "property": { "unit": "", "min": 0, "max": 100, "scale": 0, "step": 1, "type": "value" }, "type": "obj" }, { "attr": 0, "canTrigger": true, "code": "timing", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 164, "mode": "rw", "name": "定时", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "reserved2", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 165, "mode": "rw", "name": "预留2", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "log_debug", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 166, "mode": "rw", "name": "调试设置", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "clean_statistics", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 167, "mode": "rw", "name": "清洁统计", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "consumables", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 168, "mode": "rw", "name": "耗材", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "app_dev_info", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 169, "mode": "rw", "name": "App和设备", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "map_edit", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 170, "mode": "rw", "name": "地图编辑", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "multi_maps_ctrl", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 171, "mode": "rw", "name": "多地图控制", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "multi_maps_mng", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 172, "mode": "rw", "name": "多地图管理", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "station", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 173, "mode": "rw", "name": "基站", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "media_manager", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 174, "mode": "rw", "name": "媒体管理", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "reserved3", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 175, "mode": "rw", "name": "预留3", "property": { "type": "string", "maxlen": 255 }, "type": "obj" }, { "attr": 0, "canTrigger": true, "code": "unisetting", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 176, "mode": "rw", "name": "公共设置", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "error_warning", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 177, "mode": "rw", "name": "故障提醒", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "toast", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 178, "mode": "rw", "name": "提示", "type": "raw" }, { "attr": 0, "canTrigger": true, "code": "analysis", "defaultRecommend": false, "editPermission": false, "executable": true, "extContent": "", "id": 179, "mode": "rw", "name": "数据分析", "type": "raw" } ]

martijnpoppen commented 9 months ago

@john500y2k actually I did the same. I formatted the output too and also translated the names to english. From there I tried to setup a alternative mapping for the X9.

Unfortunately that's where it ends, the X9 has a different way of communicating and doesn't really seem to update all values to the dps all the time..

I was keeping a eye on @CodeFoodPixels his issue in the hope he would have a breaktrough :p

martijnpoppen commented 9 months ago

FYI, this is the mapping I came up with:

        if (config.newAPI) {
            this.PLAY_PAUSE = '151';
            this.DIRECTION = '155';
            this.WORK_MODE = '152';
            this.WORK_STATUS = '153';
            this.GO_HOME = '173';
            this.CLEAN_SPEED = '158';
            this.FIND_ROBOT = '160';
            this.BATTERY_LEVEL = '163';
            this.ERROR_CODE = '177';
        }
martijnpoppen commented 9 months ago

Also here's the list with translated names:

[
  {
    "attr": 0,
    "canTrigger": true,
    "code": "proto",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 150,
    "mode": "rw",
    "name": "Protocol",
    "property": { "type": "string", "maxlen": 255 },
    "type": "obj"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "power",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 151,
    "mode": "rw",
    "name": "Power Switch",
    "property": { "type": "bool" },
    "type": "obj"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "mode_ctrl",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 152,
    "mode": "rw",
    "name": "Mode Control",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "work_status",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 153,
    "mode": "rw",
    "name": "Work Status",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "clean_params",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 154,
    "mode": "rw",
    "name": "Cleaning Parameters",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "remote_ctrl",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 155,
    "mode": "rw",
    "name": "Remote Direction",
    "property": {
      "range": ["Brake", "Forward", "Back", "Left", "Right"],
      "type": "enum"
    },
    "type": "obj"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "pause_job",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 156,
    "mode": "rw",
    "name": "Pause and Resume",
    "property": { "type": "bool" },
    "type": "obj"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "dnd",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 157,
    "mode": "rw",
    "name": "Do Not Disturb",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "suction_level",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 158,
    "mode": "rw",
    "name": "Suction Level",
    "property": {
      "range": ["Quiet", "Standard", "Turbo", "Max"],
      "type": "enum"
    },
    "type": "obj"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "boost_iq",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 159,
    "mode": "rw",
    "name": "BoostIQ",
    "property": { "type": "bool" },
    "type": "obj"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "calling_robot",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 160,
    "mode": "rw",
    "name": "Find Robot",
    "property": { "type": "bool" },
    "type": "obj"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "volume",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 161,
    "mode": "rw",
    "name": "Volume",
    "property": {
      "unit": "",
      "min": 0,
      "max": 100,
      "scale": 0,
      "step": 1,
      "type": "value"
    },
    "type": "obj"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "user_language",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 162,
    "mode": "rw",
    "name": "Language Management",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "bat_level",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 163,
    "mode": "ro",
    "name": "Battery Level",
    "property": {
      "unit": "",
      "min": 0,
      "max": 100,
      "scale": 0,
      "step": 1,
      "type": "value"
    },
    "type": "obj"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "timing",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 164,
    "mode": "rw",
    "name": "Timing",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "reserved2",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 165,
    "mode": "rw",
    "name": "Reserved 2",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "log_debug",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 166,
    "mode": "rw",
    "name": "Debug Settings",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "clean_statistics",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 167,
    "mode": "rw",
    "name": "Cleaning Statistics",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "consumables",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 168,
    "mode": "rw",
    "name": "Consumables",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "app_dev_info",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 169,
    "mode": "rw",
    "name": "App and Device",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "map_edit",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 170,
    "mode": "rw",
    "name": "Map Editing",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "multi_maps_ctrl",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 171,
    "mode": "rw",
    "name": "Multi-Map Control",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "multi_maps_mng",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 172,
    "mode": "rw",
    "name": "Multi-Map Management",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "station",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 173,
    "mode": "rw",
    "name": "Station",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "media_manager",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 174,
    "mode": "rw",
    "name": "Media Management",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "reserved3",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 175,
    "mode": "rw",
    "name": "Reserved 3",
    "property": { "type": "string", "maxlen": 255 },
    "type": "obj"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "unisetting",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 176,
    "mode": "rw",
    "name": "Public Settings",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "error_warning",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 177,
    "mode": "rw",
    "name": "Error Warning",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "toast",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 178,
    "mode": "rw",
    "name": "Toast",
    "type": "raw"
  },
  {
    "attr": 0,
    "canTrigger": true,
    "code": "analysis",
    "defaultRecommend": false,
    "editPermission": false,
    "executable": true,
    "extContent": "",
    "id": 179,
    "mode": "rw",
    "name": "Data Analysis",
    "type": "raw"
  }
]
martijnpoppen commented 8 months ago

@CodeFoodPixels did you have any luck yet on the X8 Pro and X9?

CodeFoodPixels commented 8 months ago

Unfortunately I've been fairly busy recently. Got married, got pulled onto a special project at work and general life chaos.

I'll have a proper read through these things and see what I can figure out

On Wed, 24 Jan 2024, 19:34 Martijn Poppen, @.***> wrote:

@CodeFoodPixels https://github.com/CodeFoodPixels did you have any luck yet on the X8 Pro and X9?

— Reply to this email directly, view it on GitHub https://github.com/CodeFoodPixels/robovac/issues/28#issuecomment-1908790003, or unsubscribe https://github.com/notifications/unsubscribe-auth/ABEPFVFHL6L3LQOM2IXQ4RDYQFO4TAVCNFSM6AAAAAA5MX5AP6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSMBYG44TAMBQGM . You are receiving this because you were mentioned.Message ID: @.***>

CodeFoodPixels commented 7 months ago

So I've been looking at a way to solve this and have been working on something in the better-dps branch. It's completely untested at the moment.

Essentially, each vacuum model will have a file defining stuff like features and command codes.

ScottWoolven5 commented 7 months ago

So I've been looking at a way to solve this and have been working on something in the better-dps branch. It's completely untested at the moment.

Essentially, each vacuum model will have a file defining stuff like features and command codes.

I've just tried this branch with my Model X8 Pro (without SES) but the device was still unavailable and the error logs showed:

_Logger: homeassistant.components.vacuum Source: helpers/entity_platform.py:344 Integration: Vacuum (documentation, issues) First occurred: 21:05:59 (1 occurrences) Last logged: 21:05:59

Error while setting up robovac platform for vacuum Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 344, in _async_setup_platform await asyncio.shield(task) File "/config/custom_components/robovac/vacuum.py", line 99, in async_setup_entry entity = RoboVacEntity(item) ^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/robovac/vacuum.py", line 255, in init self.vacuum = RoboVac( ^^^^^^^^ File "/config/custom_components/robovac/robovac.py", line 14, in init if ROBOVAC_MODELS[model_code] is None:


KeyError: 'T2266'
_

I see in the Vacuums folder, there is no T2266 file. What is the best way to get the DPS in order to create a file for my vacuum?
CodeFoodPixels commented 7 months ago

It's likely not ready for anyone to use yet, I haven't even tried it on my own vacuum yet.

On Sun, 3 Mar 2024, 21:15 ScottWoolven5, @.***> wrote:

So I've been looking at a way to solve this and have been working on something in the better-dps https://github.com/CodeFoodPixels/robovac/tree/better-dps branch. It's completely untested at the moment.

Essentially, each vacuum model will have a file defining stuff like features and command codes.

I've just tried this branch with my Model X8 Pro (without SES) but the device was still unavailable and the error logs showed:

_Logger: homeassistant.components.vacuum Source: helpers/entity_platform.py:344 Integration: Vacuum (documentation, issues) First occurred: 21:05:59 (1 occurrences) Last logged: 21:05:59

Error while setting up robovac platform for vacuum Traceback (most recent call last): File "/usr/src/homeassistant/homeassistant/helpers/entity_platform.py", line 344, in _async_setup_platform await asyncio.shield(task) File "/config/custom_components/robovac/vacuum.py", line 99, in async_setup_entry entity = RoboVacEntity(item) ^^^^^^^^^^^^^^^^^^^ File "/config/custom_components/robovac/vacuum.py", line 255, in init self.vacuum = RoboVac( ^^^^^^^^ File "/config/custom_components/robovac/robovac.py", line 14, in init if ROBOVAC_MODELS[model_code] is None:


KeyError: 'T2266'
_

I see in the Vacuums folder, there is no T2266 file. What is the best way
to get the DPS in order to create a file for my vacuum?

—
Reply to this email directly, view it on GitHub
<https://github.com/CodeFoodPixels/robovac/issues/28#issuecomment-1975328209>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ABEPFVHY7YNHX52CYVIJYUDYWOHHZAVCNFSM6AAAAAA5MX5AP6VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMYTSNZVGMZDQMRQHE>
.
You are receiving this because you were mentioned.Message ID:
***@***.***>