PiotrMachowski / Home-Assistant-custom-components-Xiaomi-Cloud-Map-Extractor

This custom integration provides a way to present a live view of a map for Xiaomi (Roborock/Viomi/Roidmi/Dreame) vacuums without a need for rooting.
MIT License
1.15k stars 122 forks source link

Failed to login - Invalid calibration, please check your configuration (Roborock S4) #482

Closed c11umw closed 11 months ago

c11umw commented 11 months ago

Checklist

The problem

image

It used to work intermittently and then it stopped working and never came back (about 6 months ago) At the same time the Xiaomi app rarely displayed the map.

Since then - about 2 months ago I set the scan-interval in the config and added the "only update when cleaning" blueprint. The app now shows the map without issues.

But the map extractor never came back.

I tried moving it back to the same VLAN as my Home Assistant (even though it used to work on my IOT VLAN) and removed config / reboot / re-add config / reboot as suggested. Also tried the default "recommended" config - failed And tried putting the credentials etc directly in config rather than secrets.yaml - failed

What version of an integration has described problem?

v2.2.1

What was the last working version of an integration?

Can't Remember

What vacuum model do you have problems with?

roborock.vacuum.s4

What version of Home Assistant do you use?

2023.10.3

What type of installation are you running?

Home Assistant Supervised

Camera's configuration

# Roborock Xiaomi Cloud Map Extractor
camera:
  - platform: xiaomi_cloud_map_extractor
    host: !secret xiaomi_vacuum_host (IP in same VLAN as HA)
    token: !secret xiaomi_vacuum_token (32char code from .exe extractor tool)
    username: !secret xiaomi_cloud_username (email)
    password: !secret xiaomi_cloud_password (password)
    country: de
    scan_interval:
      seconds: 30
    draw: ["all"]
    attributes:
      - calibration_points

secrets.yaml

# Roborock Cloud Map
xiaomi_vacuum_host: 192.168.xxx.xxx
xiaomi_vacuum_token: 12345678901234567890123456789012
xiaomi_cloud_username: myemail@mydomain.com
xiaomi_cloud_password: myxiaomipassword

Errors shown in the HA logs (if applicable)

using grep -i for xiaomi

2023-10-22 06:06:18.216 INFO (MainThread) [homeassistant.setup] Setting up xiaomi_miio
2023-10-22 06:06:18.217 INFO (MainThread) [homeassistant.setup] Setup of domain xiaomi_miio took 0.0 seconds
2023-10-22 06:06:26.845 INFO (MainThread) [homeassistant.components.camera] Setting up camera.xiaomi_cloud_map_extractor
2023-10-22 06:06:26.859 INFO (MainThread) [homeassistant.components.binary_sensor] Setting up binary_sensor.xiaomi_miio
2023-10-22 06:06:26.891 INFO (MainThread) [homeassistant.components.sensor] Setting up sensor.xiaomi_miio
2023-10-22 06:06:26.898 INFO (MainThread) [homeassistant.components.button] Setting up button.xiaomi_miio
2023-10-22 06:06:26.901 DEBUG (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Logging in...
2023-10-22 06:06:26.910 INFO (MainThread) [homeassistant.components.vacuum] Setting up vacuum.xiaomi_miio
2023-10-22 06:06:26.944 DEBUG (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Failed to log in
2023-10-22 06:06:26.945 ERROR (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Unable to log in, check credentials
2023-10-22 06:06:26.945 DEBUG (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Retrieving map name from device
2023-10-22 06:06:32.146 DEBUG (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Map name rubyplus%2F261981564%2F9
2023-10-22 06:06:32.146 DEBUG (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Unable to retrieve map, reasons: Logged in - False, map name - rubyplus%2F261981564%2F9, device retrieved - False
2023-10-22 06:06:58.671 DEBUG (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Logging in...
2023-10-22 06:06:58.693 DEBUG (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Failed to log in
2023-10-22 06:06:58.693 DEBUG (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Retrieving map name from device
2023-10-22 06:06:58.838 DEBUG (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Map name rubyplus%2F261981564%2F17
2023-10-22 06:06:58.838 DEBUG (SyncWorker_2) [custom_components.xiaomi_cloud_map_extractor.camera] Unable to retrieve map, reasons: Logged in - False, map name - rubyplus%2F261981564%2F17, device retrieved - False
2023-10-22 06:07:02.372 INFO (SyncWorker_5) [homeassistant.loader] Loaded xiaomi_aqara from homeassistant.components.xiaomi_aqara
2023-10-22 06:07:28.454 DEBUG (SyncWorker_6) [custom_components.xiaomi_cloud_map_extractor.camera] Logging in...
2023-10-22 06:07:28.467 DEBUG (SyncWorker_6) [custom_components.xiaomi_cloud_map_extractor.camera] Failed to log in
2023-10-22 06:07:28.467 DEBUG (SyncWorker_6) [custom_components.xiaomi_cloud_map_extractor.camera] Retrieving map name from device
2023-10-22 06:07:28.578 DEBUG (SyncWorker_6) [custom_components.xiaomi_cloud_map_extractor.camera] Map name rubyplus%2F261981564%2F7
2023-10-22 06:07:28.578 DEBUG (SyncWorker_6) [custom_components.xiaomi_cloud_map_extractor.camera] Unable to retrieve map, reasons: Logged in - False, map name - rubyplus%2F261981564%2F7, device retrieved - False
2023-10-22 06:07:58.447 DEBUG (SyncWorker_9) [custom_components.xiaomi_cloud_map_extractor.camera] Logging in...
2023-10-22 06:07:58.463 DEBUG (SyncWorker_9) [custom_components.xiaomi_cloud_map_extractor.camera] Failed to log in
2023-10-22 06:07:58.464 DEBUG (SyncWorker_9) [custom_components.xiaomi_cloud_map_extractor.camera] Retrieving map name from device
2023-10-22 06:07:58.573 DEBUG (SyncWorker_9) [custom_components.xiaomi_cloud_map_extractor.camera] Map name rubyplus%2F261981564%2F16
2023-10-22 06:07:58.574 DEBUG (SyncWorker_9) [custom_components.xiaomi_cloud_map_extractor.camera] Unable to retrieve map, reasons: Logged in - False, map name - rubyplus%2F261981564%2F16, device retrieved - False

....

Additional information

I do have PiHole running here and have for years. Nothing caught in the logs and the main Xiaomi integration works fine. I did disable PiHole for 30mins, but the map extractor still doesn't work

PiotrMachowski commented 11 months ago

Can you check if Tokens Extractor works? https://github.com/PiotrMachowski/Xiaomi-cloud-tokens-extractor

c11umw commented 11 months ago

Yes. When I moved it back to the same VLAN as my Home Assistant I needed to re-run it to get a new token. I also had to re-add the vacuum to the Xiaomi integration due to the new IP and I needed the new token to do it - it worked.

To get it, I used the .exe version in a windows cmd prompt

c11umw commented 11 months ago

Interesting - I tried the curl version of the key extractor in Home Assistant SSH terminal and it failed.

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100   487  100   487    0     0   1005      0 --:--:-- --:--:-- --:--:--  1005
Archive:  token_extractor.zip
   creating: token_extractor/
  inflating: token_extractor/token_extractor.py
 extracting: token_extractor/requirements.txt
Requirement already satisfied: requests in /usr/lib/python3.11/site-packages (from -r requirements.txt (line 1)) (2.31.0)
Requirement already satisfied: pycryptodome in /usr/lib/python3.11/site-packages (from -r requirements.txt (line 2)) (3.19.0)
Requirement already satisfied: charset-normalizer<4,>=2 in /usr/lib/python3.11/site-packages (from requests->-r requirements.txt (line 1)) (3.3.1)
Requirement already satisfied: idna<4,>=2.5 in /usr/lib/python3.11/site-packages (from requests->-r requirements.txt (line 1)) (3.4)
Requirement already satisfied: urllib3<3,>=1.21.1 in /usr/lib/python3.11/site-packages (from requests->-r requirements.txt (line 1)) (2.0.7)
Requirement already satisfied: certifi>=2017.4.17 in /usr/lib/python3.11/site-packages (from requests->-r requirements.txt (line 1)) (2023.7.22)
WARNING: Running pip as the 'root' user can result in broken permissions and conflicting behaviour with the system package manager. It is recommended to use a virtual environment instead: https://pip.pypa.io/warnings/venv
Username (email or user ID):
myemail@mydomain.com
Password:

Server (one of: cn, de, us, ru, tw, sg, in, i2) Leave empty to check all available:
de

Logging in...
Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/urllib3/connection.py", line 203, in _new_conn
    sock = connection.create_connection(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/urllib3/util/connection.py", line 60, in create_connection
    for res in socket.getaddrinfo(host, port, family, socket.SOCK_STREAM):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/socket.py", line 962, in getaddrinfo
    for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
socket.gaierror: [Errno -5] Name has no usable address

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/urllib3/connectionpool.py", line 791, in urlopen
    response = self._make_request(
               ^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/urllib3/connectionpool.py", line 492, in _make_request
    raise new_e
  File "/usr/lib/python3.11/site-packages/urllib3/connectionpool.py", line 468, in _make_request
    self._validate_conn(conn)
  File "/usr/lib/python3.11/site-packages/urllib3/connectionpool.py", line 1097, in _validate_conn
    conn.connect()
  File "/usr/lib/python3.11/site-packages/urllib3/connection.py", line 611, in connect
    self.sock = sock = self._new_conn()
                       ^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/urllib3/connection.py", line 210, in _new_conn
    raise NameResolutionError(self.host, self, e) from e
urllib3.exceptions.NameResolutionError: <urllib3.connection.HTTPSConnection object at 0x7f809f9690>: Failed to resolve 'account.xiaomi.com' ([Errno -5] Name has no usable address)

The above exception was the direct cause of the following exception:

Traceback (most recent call last):
  File "/usr/lib/python3.11/site-packages/requests/adapters.py", line 486, in send
    resp = conn.urlopen(
           ^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/urllib3/connectionpool.py", line 845, in urlopen
    retries = retries.increment(
              ^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/urllib3/util/retry.py", line 515, in increment
    raise MaxRetryError(_pool, url, reason) from reason  # type: ignore[arg-type]
    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
urllib3.exceptions.MaxRetryError: HTTPSConnectionPool(host='account.xiaomi.com', port=443): Max retries exceeded with url: /pass/serviceLogin?sid=xiaomiio&_json=true (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x7f809f9690>: Failed to resolve 'account.xiaomi.com' ([Errno -5] Name has no usable address)"))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/config/token_extractor/token_extractor.py", line 328, in <module>
    main()
  File "/config/token_extractor/token_extractor.py", line 271, in main
    logged = connector.login()
             ^^^^^^^^^^^^^^^^^
  File "/config/token_extractor/token_extractor.py", line 99, in login
    if self.login_step_1():
       ^^^^^^^^^^^^^^^^^^^
  File "/config/token_extractor/token_extractor.py", line 44, in login_step_1
    response = self._session.get(url, headers=headers, cookies=cookies)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/requests/sessions.py", line 602, in get
    return self.request("GET", url, **kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/requests/sessions.py", line 589, in request
    resp = self.send(prep, **send_kwargs)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/requests/sessions.py", line 703, in send
    r = adapter.send(request, **kwargs)
        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/site-packages/requests/adapters.py", line 519, in send
    raise ConnectionError(e, request=request)
requests.exceptions.ConnectionError: HTTPSConnectionPool(host='account.xiaomi.com', port=443): Max retries exceeded with url: /pass/serviceLogin?sid=xiaomiio&_json=true (Caused by NameResolutionError("<urllib3.connection.HTTPSConnection object at 0x7f809f9690>: Failed to resolve 'account.xiaomi.com' ([Errno -5] Name has no usable address)"))
PiotrMachowski commented 11 months ago

Ok, so it seems that something actually blocks the traffic to Xiaomi Cloud

c11umw commented 11 months ago

Yes. Checking it now, I can ping account.xiaomi.com from my windows PC, but not from HomeAssistant terminal.

It has a different DNS assigned in Home Assistant (not sure why). Checking it now to see why that domain can't resolve

c11umw commented 11 months ago

Home Assistant uses a local DNS which isn't resolving the domain

➜  config nslookup account.xiaomi.com
Server:         172.30.32.3
Address:        172.30.32.3#53

Non-authoritative answer:
*** Can't find account.xiaomi.com: No answer

172.xxx.xxx.xxx likely being a link to local docker container. I don't use DNS tools or add-ons in HA, so it's something "core"

Looking at Home Assistant forum I see others have the same issue, but for different integrations. Will try to resolve and if I get a fix I'll post it here for others to replicate

c11umw commented 11 months ago

Fixed. It looks like the local hassio_dns container (ip: 172.30.32.3) is a localised method of forwarding DNS requests onto the DNS configured in: Home Assistant | Settings | Network

I expanded my IP4 network settings and it all looked ok

DNS Servers:
[Pihole1 ip], [PiHole2 ip], 1.1.1.2, 1.0.0.2

As a test, I went back to basics with

DNS Servers:
1.1.1.1, 1.0.0.1, 8.8.8.8, 8.8.4.4

Then, from Home Assistant SSH

➜  ~ ha dns restart

Now when I ping account.xiaomi.com it resolves. Long story short, there's something specific to my PiHole1 that's preventing it from looking up that ip. There nothing in the PiHole query logs showing it being blocked and even when disabled, it's still blocking it somehow. I even added it to the whitelist and it still blocked it (?)

Swapped my secondary to primary and it's working fine. Got the map back :)

[Pihole2 ip], [PiHole1 ip], 1.1.1.2, 1.0.0.2

Thanks for your help C