Ecovacs GOAT A1600 RTK Support
Checks
- [x] I have searched the existing issues and no issue is describing my issue
- [x] I have checked the FAQ
- [x] I have checked the documentation
- [x] I have installed the latest version
The problem
Hi,
Would it be possible to get GOAT A1600 RTK support so it could be used in Home Assistant?
On which deebot device (vacuum) you have the issue?
GOAT A1600 RTK
Which version of the deebot-client are you using?
2025.3.3
Country
fr
Continent
eu
Anything in the logs that might be useful for us?
25-03-16 10:59:02.785 WARNING (MainThread) [deebot_client.api_client] Device class "xmp9ds" not recognized. Please add support for it: {'did': '[REMOVED]', 'name': 'E0BA34765F09HYEE0049', 'class': 'xmp9ds', 'resource': '6lZMW5q0', 'company': 'eco-ng', 'bindTs': 1741714815430, 'service': {'jmq': 'jmq-ngiot-eu.dc.ww.ecouser.net', 'mqs': 'api-ngiot.dc-eu.ww.ecouser.net'}, 'deviceName': 'GOAT A1600 RTK', 'icon': 'https://portal-ww.ecouser.net/api/pim/file/get/677cfd9e954634917988358a', 'ota': True, 'UILogicId': 'goatr_ww_h_goat2', 'materialNo': '116-2337-0000', 'pid': '65d2bb29a1bbb50225b81776', 'product_category': 'GOATBOT', 'model': 'QingGeng-R', 'updateInfo': {'needUpdate': False, 'changeLog': ''}, 'nick': 'Wall-e', 'homeId': '67cdf8f592a75c00076aa7b5', 'homeSort': 1, 'status': 1, 'btName': 'GOAT-xmp9ds-0049', 'btMac': '28:F5:2B:A5:BE:D9', 'otaUpgrade': {}}
2025-03-16 10:59:02.786 WARNING (MainThread) [homeassistant.components.ecovacs.controller] Device "GOAT A1600 RTK" not supported. More information at https://github.com/DeebotUniverse/client.py/issues/612: {'did': 'da8aa19a-af0a-4b7f-84fe-2f9059143755', 'name': 'E0BA34765F09HYEE0049', 'class': 'xmp9ds', 'resource': '6lZMW5q0', 'company': 'eco-ng', 'bindTs': 1741714815430, 'service': {'jmq': 'jmq-ngiot-eu.dc.ww.ecouser.net', 'mqs': 'api-ngiot.dc-eu.ww.ecouser.net'}, 'deviceName': 'GOAT A1600 RTK', 'icon': 'https://portal-ww.ecouser.net/api/pim/file/get/677cfd9e954634917988358a', 'ota': True, 'UILogicId': 'goatr_ww_h_goat2', 'materialNo': '116-2337-0000', 'pid': '65d2bb29a1bbb50225b81776', 'product_category': 'GOATBOT', 'model': 'QingGeng-R', 'updateInfo': {'needUpdate': False, 'changeLog': ''}, 'nick': 'Wall-e', 'homeId': '67cdf8f592a75c00076aa7b5', 'homeSort': 1, 'status': 1, 'btName': 'GOAT-xmp9ds-0049', 'btMac': '28:F5:2B:A5:BE:D9', 'otaUpgrade': {}}
20
Additional information
No response
Hi, please add the Goat o800 RTK, too. Thank you.
Hi, please add the Goat o800 RTK, too. Thank you.
https://github.com/DeebotUniverse/client.py/discussions/853
Hi, I have copied the file 5xu9h3.py to 2px96q.py and it seems to work with the o800 RTK.
@diveschumi can you create a PR or tell me how to do it? Then I will try that. This will reduce the effort of the creator. Thank you!
@diveschumi can you create a PR or tell me how to do it? Then I will try that. This will reduce the effort of the creator. Thank you!
Interested too. Would you please be able to explain how to do this? Thank you!
When Home Assistant runs under docker:
- docker exec -it CONTAINERNAME sh
- cd /usr/local/lib/python3.13/site-packages/deebot_client/hardware/deebot/
- cp 5xu9h3.py 2px96q.py
Restart home assistant
You have to do this after every update from home assistant.
For any other GOAT you have to look in the debug log files for the client-id.
When Home Assistant runs under docker:
* docker exec -it CONTAINERNAME sh * cd /usr/local/lib/python3.13/site-packages/deebot_client/hardware/deebot/ * cp 5xu9h3.py 2px96q.pyRestart home assistant
You have to do this after every update from home assistant.
For any other GOAT you have to look in the debug log files for the client-id.
Thanks for your reply. Would you happen to know how to do this on HaOS? (mine is running in a proxmox VM)
Thanks for your reply. Would you happen to know how to do this on HaOS? (mine is running in a proxmox VM)
You have to login in with ssh to open the shell, but I don't know how.
Thanks for your reply. Would you happen to know how to do this on HaOS? (mine is running in a proxmox VM)
install addon "Advanced SSH & Web terminal" configure it
start addon and join web overview Login with credentials from addon
* docker exec -it homeassistant /bin/bash
* cd /usr/local/lib/python3.13/site-packages/deebot_client/Hardware/deebot
* cp 5xu9h3.py 2px96q.py
Please be sure what you are doing, no guarantee, no help. But this is how it worked for me. I just don't know how to do a PR now.
config_entry-ecovacs-01JPWWK42ZSP92AADH26V2NNW2(1).json
home-assistant_ecovacs_2025-03-21T18-37-12.778Z.log
Thanks for your reply. Would you happen to know how to do this on HaOS? (mine is running in a proxmox VM)
install addon "Advanced SSH & Web terminal" configure it
start addon and join web overview Login with credentials from addon
* docker exec -it homeassistant /bin/bash * cd /usr/local/lib/python3.13/site-packages/deebot_client/Hardware/deebot * cp 5xu9h3.py 2px96q.pyPlease be sure what you are doing, no guarantee, no help. But this is how it worked for me. I just don't know how to do a PR now.
It works sort of. Thanks for the help already. I can read all the data and change settings, but i cannot control (start/stop/pause) the robot. In the logs it gives an error.
Would anyone please be able to help out?
So what i did so far: I copied 5xu9h3.py to xmp9ds.py which allowed me to add the robot to HA. I've added the logs in attachment.
I have done some more investigation, and it seems that ecovacs has changed their protocol (but i could be mistaken).
Here is some more information:
When i trace the ecovacs app, i get the following:
POST https://api-ngiot.dc-eu.ww.ecouser.net/api/iot/endpoint/control?si=xxx&ct=q&eid=xxx&et=xmp9ds&er=xxx&apn=clean&fmt=j HTTP/2.0
mow area {"body":{"data":{"act":"start","content":{"type":"spotArea","value":"1"}}},"header":{"channel":"iOS","reqid":"fTFmzJ","ts":"1742665772353","ver":"0.0.50","m":"request","pri":1,"tzm":60,"tzc":"Europe/Paris"}}
mow auto: {"body":{"data":{"act":"start","content":{"type":"auto"}}},"header":{"channel":"iOS","reqid":"UGJUnU","ts":"1742665974433","ver":"0.0.50","m":"request","pri":1,"tzm":60,"tzc":"Europe/Paris"}}
resume mowing {"body":{"data":{"act":"resume","content":{"type":"auto"}}},"header":{"channel":"iOS","reqid":"ORfMPC","ts":"1742666047520","ver":"0.0.50","m":"request","pri":1,"tzm":60,"tzc":"Europe/Paris"}}
pause: {"body":{"data":{"act":"pause","content":{"type":"auto"}}},"header":{"channel":"iOS","reqid":"tdQclK","ts":"1742666078695","ver":"0.0.50","m":"request","pri":1,"tzm":60,"tzc":"Europe/Paris"}}
STOP {"body":{"data":{"act":"stop","content":{"type":"auto"}}},"header":{"channel":"iOS","reqid":"iBZWSW","ts":"1742666237813","ver":"0.0.50","m":"request","pri":1,"tzm":60,"tzc":"Europe/Paris"}}
When i Check the Clean and CleanV2, it seems like these are different. Actually, it needs the code from "cleanV2" on the "clean" action. Doing this, it executes start and pause correctly, but i cannot resume. @edenhaus would you please be able to help me out? I can provide any information you need, and do the testing of course.
config_entry-ecovacs-01JPWWK42ZSP92AADH26V2NNW2(1).json
home-assistant_ecovacs_2025-03-21T18-37-12.778Z.log
Thanks for your reply. Would you happen to know how to do this on HaOS? (mine is running in a proxmox VM)
install addon "Advanced SSH & Web terminal" configure it start addon and join web overview Login with credentials from addon
* docker exec -it homeassistant /bin/bash * cd /usr/local/lib/python3.13/site-packages/deebot_client/Hardware/deebot * cp 5xu9h3.py 2px96q.pyPlease be sure what you are doing, no guarantee, no help. But this is how it worked for me. I just don't know how to do a PR now.
It works sort of. Thanks for the help already. I can read all the data and change settings, but i cannot control (start/stop/pause) the robot. In the logs it gives an error.
Would anyone please be able to help out?
So what i did so far: I copied 5xu9h3.py to xmp9ds.py which allowed me to add the robot to HA. I've added the logs in attachment.
I might be dumb, but the folder /usr/local/lib/python3.13 doesn't exist on my installation of HASS-OS... The only folder that exists in /usr/local/lib is perl5. Am I missing something obvious???
Hi, please add the Goat o800 Panorama, too. It cannot be detected by the integration. Thank you.
Did the same for the Goat o500 panorama (id: 300lc5). However, the actions (start, stop, home, pause) also do not work.
How is the progress on this implementation
I have done some more investigation, and it seems that ecovacs has changed their protocol (but i could be mistaken).
Here is some more information:
When i trace the ecovacs app, i get the following:
POST https://api-ngiot.dc-eu.ww.ecouser.net/api/iot/endpoint/control?si=xxx&ct=q&eid=xxx&et=xmp9ds&er=xxx&apn=clean&fmt=j HTTP/2.0
mow area {"body":{"data":{"act":"start","content":{"type":"spotArea","value":"1"}}},"header":{"channel":"iOS","reqid":"fTFmzJ","ts":"1742665772353","ver":"0.0.50","m":"request","pri":1,"tzm":60,"tzc":"Europe/Paris"}}
mow auto: {"body":{"data":{"act":"start","content":{"type":"auto"}}},"header":{"channel":"iOS","reqid":"UGJUnU","ts":"1742665974433","ver":"0.0.50","m":"request","pri":1,"tzm":60,"tzc":"Europe/Paris"}}
resume mowing {"body":{"data":{"act":"resume","content":{"type":"auto"}}},"header":{"channel":"iOS","reqid":"ORfMPC","ts":"1742666047520","ver":"0.0.50","m":"request","pri":1,"tzm":60,"tzc":"Europe/Paris"}}
pause: {"body":{"data":{"act":"pause","content":{"type":"auto"}}},"header":{"channel":"iOS","reqid":"tdQclK","ts":"1742666078695","ver":"0.0.50","m":"request","pri":1,"tzm":60,"tzc":"Europe/Paris"}}
STOP {"body":{"data":{"act":"stop","content":{"type":"auto"}}},"header":{"channel":"iOS","reqid":"iBZWSW","ts":"1742666237813","ver":"0.0.50","m":"request","pri":1,"tzm":60,"tzc":"Europe/Paris"}}
When i Check the Clean and CleanV2, it seems like these are different. Actually, it needs the code from "cleanV2" on the "clean" action. Doing this, it executes start and pause correctly, but i cannot resume. @edenhaus would you please be able to help me out? I can provide any information you need, and do the testing of course.
Would you mind terribly, explaining which files you changed to get it to start and what you actually changed? I'm by no means a coder.
Right now, all I care about is getting my mower to start on a schedule using home assistant instead of relying on the Ecovacs-app.
@dcollewaert Sorry for the delay but I missed your question. Feel free to write me a PM on Discord. My username is edenhaus
@yeyeoke dcollewaert is analyzing the traffic between the app and the ecovacs servers. This is required as the first step to get it working later in HA. Please be patient and wait if you don't have the technical skills to analyze the traffic
Hello,
I copied 5xu9h3.py to xmp9ds.py and I see A1600, but some features are disabled.
I would love to be able to automate A1600, there is one feature missing in the app, which is crucial for me - mow direction for each zone - that wuld be possible with HA.
Can I help somehow?
Thank you
I extract some additional request/response for the A1600 RTK firmware 1.7.80:
{"body":{"data":["getCutEfficiency","getObstacleHeight","getCutHeight","getCutDirection","getAutoCutDirection","getRainDelay","getAnimProtect","getTimeZone","getCustomCutMode","getBorderSwitch"]}
{"header":{"tzm":120,"ts":"1746483121900561666","fwVer":"1.7.80"},"body":{"code":0,"msg":"ok","data":{"getCutEfficiency":{"data":{"level":2},"code":0,"msg":"ok"},"getObstacleHeight":{"data":{"level":2},"code":0,"msg":"ok"},"getCutHeight":{"data":{"level":4},"code":0,"msg":"ok"},"getCutDirection":{"data":{"angle":270,"set":0},"code":0,"msg":"ok"},"getAutoCutDirection":{"data":{"enable":1},"code":0,"msg":"ok"},"getRainDelay":{"data":{"enable":1,"delay":180},"code":0,"msg":"ok"},"getAnimProtect":{"data":{"enable":1,"start":"19:0","end":"7:0"},"code":0,"msg":"ok"},"getTimeZone":{"data":{"tzm":120,"isReset":1},"code":0,"msg":"ok"},"getCustomCutMode":{"data":{"enable":1},"code":0,"msg":"ok"},"getBorderSwitch":{"data":{"enable":1,"mode":1},"code":0,"msg":"ok"}}}}
{"body":{"data":["getError","getRTK","getRTKOta"]}
{"header":{"tzm":120,"ts":"1746483108116909076","fwVer":"1.7.80"},"body":{"code":0,"msg":"ok","data":{"getError":{"code":0,"msg":"","data":{"code":[0]}},"getRTK":{"data":{"result":0,"rtks":[{"x":10,"y":53,"sn":"XXXXX","state":0,"mode":0,"star":29,"version":"XXXXX 1.3.1"}],"observations":{"solStat":0,"poseType":50,"roverId":"XXXXX","roverSvs":32,"roverSolnSvs":29,"roverSignalRate":42,"roverSignalScore":86,"roverOcclusionRate":26,"baseStnId":"\"2318\"","baseSolnSvs":33,"baseSignalRate":44,"baseSignalScore":92,"baseOcclusionRate":23}},"code":0,"msg":"ok"},"getRTKOta":{"code":0,"msg":"ok","data":{"needUpdate":0,"poleState":0,"movState":2,"poleProgress":0,"movProgress":100,"totalProgress":100,"rtkOtaResult":2,"forceUpdate":0,"otaMinute":0,"otaMethod":0,"currentVersion":"","newVersion":""}}}}}
This is auto mow on for RTK O800 https://api-ngiot.dc-eu.ww.ecouser.net/api/iot/endpoint/control?si=xxx&ct=q&eid=xxx&et=2px96q&er=xxx&apn=clean&fmt=j
{
"body": {
"data": {
"act": "start",
"content": {
"type": "auto"
}
}
},
"header": {
"channel": "Android",
"m": "request",
"pri": 2,
"reqid": "iw7ETJ",
"ts": "1747742911408",
"tzc": "Europe/London",
"tzm": 60,
"ver": "0.0.22"
}
}
I can get more if needed
It looks like my robot vacuum also uses the endpoint /iot/endpoint/control rather than iot/devmanager.do within the app (my vacuum can be controlled fine by the integration).
I'm guessing endpoint/control is a new endpoint that will takeover from devmanager.do.
Also I think that these are the same:- https://api-ngiot.dc-eu.ww.ecouser.net/api/iot/endpoint/control https://portal-eu.ecouser.net/api/iot/endpoint/control
some more notes...
async def _execute_api_request(
self, authenticator: Authenticator, device_info: ApiDeviceInfo
) -> dict[str, Any]:
payload = {
"cmdName": self.NAME, # doesn't exist
"payload": self._get_payload(),
"payloadType": self.DATA_TYPE.value, # http param renamed to fmt
"td": "q", # http param renamed to ct
"toId": device_info["did"], # http param renamed to eid
"toRes": device_info["resource"], # http param renamed to er
"toType": device_info["class"], # http param renamed to et
# new http param si (some random id which matches request header X-ECO-REQUEST-ID)
# new http param apn (clean|charge)
}
Instead comment code snippets here, can you open a PR for your changes :) We can than discuss your changes directly in the PR and it's easier for me to follow :)
Instead comment code snippets here, can you open a PR for your changes :) We can than discuss your changes directly in the PR and it's easier for me to follow :)
Sorry I wish I could but my python skills don't exist, I understand APIs but as for trying to make this work in python I don't really know where to start