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

Experimenting with an unsupported model, Polaris 9650iq #20

Open
VynDesign opened this issue Jun 27, 2024 · 14 comments
Open

Experimenting with an unsupported model, Polaris 9650iq #20

VynDesign opened this issue Jun 27, 2024 · 14 comments

Comments

@VynDesign
Copy link

I figured I'd give it a try, what the heck. The attributes shown are accurately returning my account information, so the authentication is working, but I'm getting the "Device does not belong to user" status reported:

Screenshot 2024-06-27 170212

I'm willing to do any legwork you would like for me to assist with getting this model supported. If you have a basic postman collection I can use to start investigating my specific model, please share it.

@galletn
Copy link
Owner

galletn commented Jun 28, 2024

Hi there!

the good news is, it's not the first time we get this error back, mostly it was because multiple devices exist on the account, and for example some of the equipment returns null for owner id, when you then request further data it returns this error.

Now let's hope it's something like that, and not that you need yet another API, then we will need to use a proxy to trace what api's are called.

attached the postman collection, login, then get devices, and please post that reply here so that I can have a first look at what happens.

New Collection Test.postman_collection.json

@VynDesign
Copy link
Author

I figured out which values from the 'login' response were required for subsequent calls. It was a little confusing which token was needed by the device /shadow, /features, and /site endpoints as the names varied and didn't exactly match what was in the login response - turns out it was the userPoolOAuth.IdToken value. I modified the postman collection to use collectionVariables to store the values necessary, and then the subsequent calls reference the collectionVariables:

iAquaLink Robot API template.postman_collection.json

You just need to input the username and password for your specific account, and the rest get populated when you hit 'login' and then 'devices':

Screenshot 2024-06-28 101433

I can get the list of devices (I only have the one):

Screenshot 2024-06-28 103326

Unfortunately, when I attempt to get the /shadow, /features, or /site, I get the "Device does not belong to user" response (in various formats):

Screenshot 2024-06-28 103656

Screenshot 2024-06-28 103214

Screenshot 2024-06-28 103956

@galletn
Copy link
Owner

galletn commented Jun 28, 2024

I'm afraid this will not be a quick fix. I'm investigating on changing the code towards socket instead of the http calls. I'll keep you posted once I'm getting there. Maybe they don't require the same inputs in order to get your device info. For sure these http calls have very different behaviour depending on the device.

You could install MITM proxy and check what calls are done.

Don't know what your experience is in that area...

And thanks for the adjustments to the postman collection!

@galletn
Copy link
Owner

galletn commented Jun 28, 2024

Good news is I found some time to check out the websocket thing, seems to be fairly easy.

Can you try and run following Python code: (replace with your credentials and device ID


import asyncio
import json
import datetime
import requests
import websocket
from websockets.sync.client import connect

def run():
        attributes = {}
        headers = {"Content-Type": "application/json; charset=utf-8", "Connection": "keep-alive", "Accept": "*/*" }
        url = "https://prod.zodiac-io.com/users/v1/login"
        data = {"apikey": "EOOEMOW4YR6QNB07", "email": "$mail$", "password": "$Pass$"}
        data = json.dumps(data)
        response = requests.post(url, headers = headers, data = data)
        print(response)

        if response.status_code == 200:
            data = response.json()
            first_name = data["first_name"]
            last_name = data["last_name"]
            authentication_token = data["authentication_token"]
            id =  data["id"]
            id_token = data["userPoolOAuth"]["IdToken"]

        print(id_token)

        message = { "action": "subscribe", "namespace": "authorization", "payload": { "userId": id }, "service": "Authorization", "target": "$Device Serial Number$", "version": 1 }
        y = json.dumps(message)

        with connect("wss://prod-socket.zodiac-io.com/devices", additional_headers={"Authorization": id_token}) as websocket:
            websocket.send(y)
            message = websocket.recv()
            
        print(message)

run()

@VynDesign
Copy link
Author

It gets the JWT just fine, but then hangs until it closes the connection:

  File "c:\Users\vynsa\Dev\python\iAquaLink\main.py", line 41, in <module>
    run()
  File "c:\Users\vynsa\Dev\python\iAquaLink\main.py", line 37, in run
    message = websocket.recv()
              ^^^^^^^^^^^^^^^^
  File "C:\Users\vynsa\AppData\Local\Programs\Python\Python311\Lib\site-packages\websockets\sync\connection.py", line 201, in recv
    raise self.protocol.close_exc from self.recv_events_exc
websockets.exceptions.ConnectionClosedOK: received 1001 (going away) Going away; then sent 1001 (going away) Going away

I also tried this in postman, no response is received:

Screenshot 2024-06-28 152115

@VynDesign
Copy link
Author

As for mitmproxy I have it installed, but don't really get how to use it just yet. I can see traffic from my laptop, but not other devices on the network from what I can tell. I was also using wireshark, but haven't seen any traffic to/from my vacuum's IP address. If you have any pointers, I'm all ears.

@falinka
Copy link

falinka commented Jun 30, 2024

It gets the JWT just fine, but then hangs until it closes the connection:

  File "c:\Users\vynsa\Dev\python\iAquaLink\main.py", line 41, in <module>
    run()
  File "c:\Users\vynsa\Dev\python\iAquaLink\main.py", line 37, in run
    message = websocket.recv()
              ^^^^^^^^^^^^^^^^
  File "C:\Users\vynsa\AppData\Local\Programs\Python\Python311\Lib\site-packages\websockets\sync\connection.py", line 201, in recv
    raise self.protocol.close_exc from self.recv_events_exc
websockets.exceptions.ConnectionClosedOK: received 1001 (going away) Going away; then sent 1001 (going away) Going away

I also tried this in postman, no response is received:

Screenshot 2024-06-28 152115

Hi VynDesign,
I think i had the similar issue, timing out on the same place forever. Can you try to manually put the serial number of your device in the script, instead of having it as variable ("target": "$Device Serial Number$" replace with "target": "Q9Zxxxxx")?

@VynDesign
Copy link
Author

Yeah, I had already done that. And, unfortunately, now I won't be able to test for a while, as my robot is out of commission. One of the wheel motors went bad, so I'm waiting on a new motor block :(

@galletn
Copy link
Owner

galletn commented Jul 2, 2024

too bad, ping me once you have it back, or we can check with what was still of last values... its not that important that it is online. if you are willing send me over your credentials (after you changed your pass first) then I can have a look. You can send them to [email protected]

@falinka
Copy link

falinka commented Jul 3, 2024

Is the robot out of game, or just you cannot start the cleaning mode? I believe plenty of valuable data can be gathered via MITM, in order to get modes, set modes :) Anyway, good luck with replacement, hope you don't for a long time.

@VynDesign
Copy link
Author

VynDesign commented Jul 3, 2024

The motor is replaced, but I'm getting Err10 on the control unit now 😒. I have a few other pieces that need replacing, which is probably causing slipping gears at the wheels. We're gearing up for our 4th of July party, so won't be able to do much until the weekend at this point.

@RogueDruid
Copy link

The motor is replaced, but I'm getting Err10 on the control unit now 😒. I have a few other pieces that need replacing, which is probably causing slipping gears at the wheels. We're gearing up for our 4th of July party, so won't be able to do much until the weekend at this point.

err 10 is communication error. Most likely due to a cable getting pulled out of place where it connects to the control board. If you open up the connector there are screws to tighten the terminals.

@galletn
Copy link
Owner

galletn commented Aug 1, 2024

hi @VynDesign the good news is that I found what is wrong for you, its the same is #4 you have an i2d_robot, and that model uses other endpoints/api's. The owner of the other thread has shared me his credentials and will put the robot in the pool next week, so I should be able to debug what needs to be done to get i2d_robot model supported too! Hope it will all be done by the time you have yours back!

@galletn
Copy link
Owner

galletn commented Aug 8, 2024

@VynDesign https://github.com/galletn/iaqualink/tree/galletn-patch-4 contains the required code for your robot, can you test it?

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

No branches or pull requests

4 participants