Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

API 190 Error #234

Closed
Shirotaku opened this issue Apr 25, 2024 · 14 comments · Fixed by #236
Closed

API 190 Error #234

Shirotaku opened this issue Apr 25, 2024 · 14 comments · Fixed by #236

Comments

@Shirotaku
Copy link

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

@Shirotaku
Copy link
Author

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

@NdK73
Copy link

NdK73 commented May 1, 2024

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

@Jeffnl98
Copy link

Jeffnl98 commented May 1, 2024

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

@Shirotaku
Copy link
Author

@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.

@Jaheiro
Copy link

Jaheiro commented May 13, 2024

Hi Folks, it seems that this 190 error is thrown in response to request in following method: https://github.com/Danielhiversen/pySwitchbot/blob/343f6ccecb357245316aa3d7508372e8f8010006/switchbot/devices/lock.py#L90

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 :(

@micaelp
Copy link

micaelp commented May 16, 2024

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?

@alexschultze
Copy link

+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.

@Jaheiro
Copy link

Jaheiro commented May 16, 2024

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.

@alexschultze
Copy link

alexschultze commented May 21, 2024

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

@alexschultze
Copy link

alexschultze commented May 21, 2024

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")

`

@dsypniewski
Copy link
Contributor

@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?

@dsypniewski
Copy link
Contributor

@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.

@Shirotaku
Copy link
Author

@alexschultze your code worked perfectly for me, thanks!

@hsakoh
Copy link

hsakoh commented May 22, 2024

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

8 participants