Danielhiversen/pySwitchbot

API 190 Error

Closed this issue · 14 comments

Hello,

When running the get_encryption_key script, I get API 190 error. That's the same error that I get when logging into HAs Bluetooth integration. Any ideas?

pySwitchbot-0.45.0>get_encryption_key.py MAC EMAIL Password: Unexpected status code returned by SwitchBot API: 190

@Danielhiversen do you think you can look into this? :)

Same here. Maybe it's related to changes in the API?

Same for me. tried to make a new bluetooth proxy and moved it nearby but still the same error....

@NdK73 @Jeffnl98 Hey, I've opened a ticket in SwitchBot's API Repository (OpenWonderLabs/SwitchBotAPI#296). Maybe give them a heads-up, too, so they can fix this issue asap.

Hi Folks, it seems that this 190 error is thrown in response to request in following method:

def retrieve_encryption_key(device_mac: str, username: str, password: str):

If i understand correctly, code is not using Switchbot Api from @Shirotaku comment but rather tries to communicate with Switchbot servers with same request app would do.

Unfortunately i don't have idea, how we could figure out what changed in their internal API, that throws error 190 now.
I tried to find a way we could get encryption key from their SwitchbotAPI instead, but with no luck, device info and device status is rather vague, especially if you don't have Switchbot Hub like me :(

Hi @Jaheiro the creator of the Switchbot MQTT service for HA (https://github.com/hsakoh) advised there was a new API URL however I am currently still getting error 190 (the example code he gave me elaborates on this saying I am not the device owner). I've been back and forth with Switchbot for the last week and they removed my lock from all accounts I believe. I've just re-registered and recalibrated and still get the same error! @Shirotaku linked to the API repo chat above which may, or may not help?

+1 one this issue. Initially error 190 through home assistant and also through pySwitchbot now.
I assumed it may be related to app login so i deleted my complete app account and readded it, with no success.

Howdy @micaelp, i'm guessing that along with that url change for API, something else had to change as well.
I think problem is not in this api https://github.com/OpenWonderLabs/SwitchBotAPI as it is different url, but rather in internal communication that Switchbot created for their mobile application and both HA integration and pySwitchbot uses.

I suspect, they might have changed way that Switchbot application authorizes itself to get encryption keys of lock device, to send commands directly to the lock through bluetooth so we're sending request to proper place, but server can't confirm that we're actual owner of that specific lock.

The cognito pool has changed, and the new pool has SRP auth. I have tried implementing an SRP authentification into the new pool, but so far I could not get it to work (using my APP ID credentials). Maybe there is some caveat to the credentials to be used to identify to the AWS cognito pool.

"CognitoUserPool": { "Default": { "PoolId": "us-east-1_S5kbwuSkN", "AppClientId": "7o4edsh9v2glcmvu821m5c8pod", "AppClientSecret":"2bkcq702hj97gucjiricvl14hd3uqebifqimk93t6h04gkj2f4a", "Region": "us-east-1" }

@bdraco
@dsypniewski

So the assumption that the identification has changed was somewhat correct.

  1. The access_token is now requested from url="https://account.api.switchbot.net/account/api/v1/user/login", including additional information in the request (clientID ).
    { "clientId": "xxxxxxx", "username": "app user", "password": app pass", "grantType": "password", "verifyCode": ""}

The client id is found in "resources\assets\switchbot_config.json".

  1. The following request to to "https://wonderlabs.eu.api.switchbot.net/wonder/keys/v1/communicate" is as usual with the new access_token.

Find below a minimal working example attached.

import requests
import json

@staticmethod
def retrieve_encryption_key(device_mac: str, username: str, password: str):
    """Retrieve lock key from internal SwitchBot API."""
    device_mac = device_mac.replace(":", "").replace("-", "").upper()

    

    
    auth_response  = requests.post(
            url = "https://account.api.switchbot.net/account/api/v1/user/login",
             json={
                # clientID in resources\assets\switchbot_config.json
                "clientId": "5nnwmhmsa9xxskm14hd85lm9bm",
                "username": username,
                "password": password,
                "grantType": "password",
                "verifyCode": ""
            },
            timeout=10,
        )
       
    print(auth_response.content);
    
    auth_response_content = json.loads(auth_response.content)
    print(auth_response_content);
    access_token = auth_response_content["body"]["access_token"]
    
    print(access_token);


    key_response = requests.post(
        url="https://wonderlabs.eu.api.switchbot.net/wonder/keys/v1/communicate",
        headers={"authorization": access_token},
        json={
            "device_mac": device_mac,
            "keyType": "user",
        },
        timeout=10,
    )

   
    key_response_content = json.loads(key_response.content);
    print('keyID:')
    print(key_response_content["body"]["communicationKey"]["keyId"])
    print('key:')
    print(key_response_content["body"]["communicationKey"]["key"])
    return {
        "key_id": key_response_content["body"]["communicationKey"]["keyId"],
        "encryption_key": key_response_content["body"]["communicationKey"]["key"],
    }
    
        
retrieve_encryption_key("FFFFFFFFFF","app_user", "app_pass")

`

@alexschultze Thanks for tagging me, I missed this issue.

I've looked into this a little bit as well and at least for me just updating the PoolId to the new one (us-east-1_S5kbwuSkN) without changing the AppClientId and AppClientSecret seems to work fine without needing to change anything else in the authentication flow. But my account also worked fine with the previous PoolId so could others verify that it works for their (possibly newer) accounts as well?

@alexschultze also the authentication flow you posted unfortunately doesn't work for my account and returns the 190 error, so it would seem to me that there is some kind of divide in SwitchBot accounts that we'd need to figure out. One option that comes to mind is just try both auth methods and one should succeed.

@alexschultze your code worked perfectly for me, thanks!

@dsypniewski

I have implemented some additional ideas. (This is a cross-post)
https://gist.github.com/hsakoh/fdeadc915b7c62ed443604ad3b364f2d

  1. Retrieving the access token
    https://account.api.switchbot.net/account/api/v1/user/login
  2. Determining the botRegion
    https://account.api.switchbot.net/account/api/v1/user/userinfo
  3. Obtaining the key and keyId
    https://wonderlabs.{botRegion}.api.switchbot.net/wonder/keys/v1/communicate

Whether the botRegion obtained in Step 2's UserInfo is wonderlabs.{botRegion} will require verification by various users.
(At least for Japanese users, ap is returned, so it worked correctly.)

If these steps are implemented in PySwitchbot, it might make the setup process easier for everyone.