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

Support vacuums #23

Open
johntdyer opened this issue Sep 22, 2022 · 31 comments
Open

Support vacuums #23

johntdyer opened this issue Sep 22, 2022 · 31 comments
Labels
enhancement New feature or request help wanted Extra attention is needed

Comments

@johntdyer
Copy link

Would he awesome to support Jandy integrated pool vacuums, at the very least I would love to stop / start and see time to completion... Is the Jandy api documented anywhere?

@johntdyer
Copy link
Author

this project looks interesting
https://github.com/tekkamanendless/iaqualink

@flz flz added enhancement New feature or request help wanted Extra attention is needed labels Oct 17, 2022
@flz
Copy link
Owner

flz commented Oct 17, 2022

I don't have one of those so unless this changes, I won't be working on adding support.

Happy to review patches though!

@galletn
Copy link

galletn commented Apr 14, 2023

Hi Guys,

Glad I found this! I have the code, could you please help to put it in correctly?

image

@galletn
Copy link

galletn commented Apr 14, 2023

import json
import datetime
from homeassistant.helpers.entity import Entity
from datetime import timedelta
from homeassistant.util import Throttle

URL_LOGIN="https://prod.zodiac-io.com/users/v1/login"
URL_GET_DEVICES="https://r-api.iaqualink.net/devices.json"
URL_GET_DEVICE_STATUS="https://prod.zodiac-io.com/devices/v1/"

SCAN_INTERVAL = timedelta(seconds=30)

def setup_platform(hass, config, add_devices, discovery_info=None):
    """Setup the sensor platform."""
    add_devices([iaqualinkRobotSensor(config)])

class iaqualinkRobotSensor(Entity):
    def __init__(self, config):
        self._name = config.get('name')
        self._username = config.get('username')
        self._password = config.get('password')
        self._api_key = config.get('api_key')

        self._headers = {"Content-Type": "application/json; charset=utf-8", "Connection": "keep-alive", "Accept": "*/*" }

        self._attributes = {}

        # Apply throttling to methods using configured interval
        self.update = Throttle(SCAN_INTERVAL)(self._update)

        self._update()

    @property
    def name(self):
        return self._name 

    @property
    def username(self):
        return self._username

    @property
    def frist_name(self):
        return self._first_name

    @property
    def last_name(self):
        return self._last_name

    @property
    def serial_number(self):
        return self._serial_number

    @property
    def state(self):
        """Return the state of the sensor."""
        return self._state

    @property
    def device_state_attributes(self):
        """Return device specific state attributes."""
        return self._attributes

    @property
    def extra_state_attributes(self):
        """Return entity specific state attributes."""
        return self._attributes

    def _update(self):
        self._attributes['username'] = self._username
        url = URL_LOGIN
        data = {"apikey": self._api_key, "email": self._username, "password": self._password}
        data = json.dumps(data)
        response = requests.post(url, headers = self._headers, data = data)
        self._state = response.status_code
        if response.status_code == 200:
            data = response.json()
            self._first_name = data["first_name"]
            self._last_name = data["last_name"]
            self._attributes['first_name'] = self._first_name
            self._attributes['last_name'] = self._last_name
            self._authentication_token = data["authentication_token"]
            self._id =  data["id"]
            self._id_token = data["userPoolOAuth"]["IdToken"]

            url = URL_GET_DEVICES
            data = None
            response = requests.get(url, headers = self._headers, params = {"authentication_token":self._authentication_token,"user_id":self._id,"api_key":self._api_key})
            
            if response.status_code == 200:
                data = response.json()
                self._serial_number = data[0]["serial_number"] #assumption only 1 robot for now
                self._attributes['serial_number'] = self._serial_number

                url = URL_GET_DEVICE_STATUS + self._serial_number + "/shadow"
                data = None
                self._headers = {"Content-Type": "application/json; charset=utf-8", "Connection": "keep-alive", "Accept": "*/*", "Authorization" : self._id_token}
                response = requests.get(url, headers = self._headers)
                if response.status_code == 200:
                    data = response.json()
                    self._state = data["state"]["reported"]["aws"]["status"]
                    self._last_online = datetime_obj = datetime.datetime.fromtimestamp((data["state"]["reported"]["aws"]["timestamp"]/1000)) #Convert Epoch To Unix
                    self._attributes['last_online'] = self._last_online
                    self._temperature = data["state"]["reported"]["equipment"]["robot"]["sensors"]["sns_1"]["val"]
                    self._attributes['temperature'] = self._temperature
                    self._pressure = data["state"]["reported"]["equipment"]["robot"]["sensors"]["sns_2"]["state"]
                    self._attributes['pressure'] = self._pressure
                    self._total_hours = data["state"]["reported"]["equipment"]["robot"]["totalHours"]
                    self._attributes['total_hours'] = self._total_hours
                    self._error_state = data["state"]["reported"]["equipment"]["robot"]["errorState"]
                    self._attributes['error_state'] = self._error_state
                    self._lift_control = data["state"]["reported"]["equipment"]["robot"]["liftControl"]
                    self._attributes['lift_control'] = self._lift_control
                    self._equipment_id = data["state"]["reported"]["equipment"]["robot"]["equipmentId"]
                    self._attributes['equipment_id'] = self._equipment_id
                    self._cycle_start_time = datetime_obj = datetime.datetime.fromtimestamp(data["state"]["reported"]["equipment"]["robot"]["cycleStartTime"])
                    self._attributes['cycle_start_time'] = self._cycle_start_time
                else:
                    self._state = response.text[:250]
            else:
                self._state = response.text[:250]



Config File:

    - platform: iaqualink
      username: 
      password: 
      api_key: EOOEMOW4YR6QNB07
      name: Bobby

@flz
Copy link
Owner

flz commented Apr 14, 2023

There's some commonalities with the exo code (namely the /shadow part). I don't have the equipment which makes testing of an unpublished API impossible.

The exo code is in a separate "exo" branch and hasn't been merged since testing by the community has been limited and the API broke at some point (I think it's working again?).

@johntdyer
Copy link
Author

johntdyer commented Apr 14, 2023

@galletn how about we create a new integration just for the robots ? I would be happy to help

@bertocea85
Copy link

hello! yes, that would be fine, I have a polaris and could help in whatever is needed.

@galletn
Copy link

galletn commented Apr 26, 2023

I have a quite busy period at work, but let me see what I can do. I already have the separate one, but I did not publish it yet.

@galletn
Copy link

galletn commented Apr 26, 2023

If you already want to test the basics, this should read out your robot.

add the extracted folder to your custom components folder.
entry in the config File:
sensor:
- platform: iaqualink
username:
password:
api_key: EOOEMOW4YR6QNB07
name:

iaqualink.zip

@bertocea85
Copy link

thanks @galletn!
this part
sensor:

  • platform: iaqualink
    username:
    password:
    api_key: EOOEMOW4YR6QNB07
    name:

directly in configuration.yaml?

gives the following error

Registrar: homeassistant.setup
Source: setup.py:251
First Occurred 14:24:48 (1 occurrences)
Last logged 14:24:48
Error in iaqualink custom integration setup: No setup or config entry setup function defined.

@bertocea85
Copy link

I have already managed to make it appear as an entity within home assistant.
the robot's data appears.
but there is this error message.
{'message': "Authorization header requires 'Credential' parameter. Authorization header requires 'Signature' parameter. Authorization header requires 'SignedHeaders' parameter. Authorization header requires existence of either a 'X-Amz-Date' or a 'Date' header.

image

@galletn
Copy link

galletn commented Apr 27, 2023

I'll try to send you my postman collection to see which of the URL's it is that gives you this error, for me it still works, so I think depending on the type of robot another URL might be needed to get some of the details. of your robot. You know how to work with postman?

@bertocea85
Copy link

thank you @galletn
yes, I can manage with postman.
I see that the app makes POST calls passing a signature, timestamp and user_id field.
The url is https://r-api.iaqualink.net/v2/devices/{serialnumber}/control.json and adds the mentioned fields.

@galletn
Copy link

galletn commented May 12, 2023

Sorry it took some time, but please find the postman collection included. I put $ where you should change some values.
Iaqualink.zip

@ppastur
Copy link

ppastur commented May 19, 2023

Hey guys I've been following along and am keen to help where I can - perhaps to test as I'm an amateur at development. I have a EX4000 iQ Robotic cleaner and although I cant seem to get the sensor working in HA, I have so far been able to (using postman) log in and get my device. For get device status, features, site etc , I can't seem to figure out what I'm supposed to use as the Authorization: $AuthKey. I assume its in the login response??
Your thoughts and guidance is appreciated.

@bertocea85
Copy link

Exactly! it asks for some kind of Authkey. Using Mitm I see that it sends a GET request (https://r-api.iaqualink.net/v2/devices.json?user_id=xxxxxx&signature=xxxxxxxxxxxxxxxxxxxxxxxxxx&timestamp=1683565854) and passes three values. User_id, signature and Timestamp. These last two I think are calculated somehow?

@ppastur
Copy link

ppastur commented May 19, 2023

I just got past this stage and can successfully run get device status. So now I can run, login, get devices, get device status, get device features and get device site. I still cant get the sensor to show up in HA though :(

@ppastur
Copy link

ppastur commented May 19, 2023

@bertocea85 I used "RefreshToken" as the $AuthKey I received on login. I also changed the URL in GetDeviceFeatures to be;
https://prod.zodiac-io.com/devices/v2/XXXMYSERIALNUMBERXXX/features

Where XXXMYSERIALNUMBERXXX=my robot serial number reported from the login stage. I mention this because the original postman collection indicated $deviceID$ which is an entirely different number.
How did you get the sensor to show up in HA?

I added the extracted folder (iaqualink.zip) to my custom components folder. I added the following to my config.yaml:
- platform: iaqualink
username: !secret iaqualink_username
password: !secret iaqualink_password
api_key: EOOEMOW4YR6QNB07
name: Fred

What have I missed?

@bertocea85
Copy link

bertocea85 commented May 19, 2023

I understand that the iaqualink folder is inside custom_components (custom_components/iaqualink/xx.py).
I have added in sensors.yaml

  • platform: iaqualink
    username: !secret iaqualink_username
    password: !secret iaqualink_password
    api_key: EOOEMOW4YR6QNB07
    name: XXX

And in configuration.yaml at the end of the file:
sensor: !include sensors.yaml
Once restarted, in the part of Settings, Devices and services, in Entities, you should see the name that you have put as a sensor.

@ppastur
Copy link

ppastur commented May 20, 2023

I understand that the iaqualink folder is inside custom_components (custom_components/iaqualink/xx.py). I have added in sensors.yaml

  • platform: iaqualink
    username: !secret iaqualink_username
    password: !secret iaqualink_password
    api_key: EOOEMOW4YR6QNB07
    name: XXX

And in configuration.yaml at the end of the file: sensor: !include sensors.yaml Once restarted, in the part of Settings, Devices and services, in Entities, you should see the name that you have put as a sensor.

I see it but other than the number 500 (state) its empty. Today for some reason I get an empty response when I run GetDevices in postman

@ppastur
Copy link

ppastur commented May 20, 2023

Ok - I figured it out. I had to modify sensor.py. line 110 is trying to map

self._temperature = data["state"]["reported"]["equipment"]["robot"]["sensors"]["sns_1"]["val"]
but it should be (in my case)
self._temperature = data["state"]["reported"]["equipment"]["robot"]["sensors"]["sns_1"]["state"]

so now I get this
image

@ppastur
Copy link

ppastur commented May 20, 2023

and here is where I got to
image

I added a few more attributed such as running state and canister empty/ok

@LOki61
Copy link

LOki61 commented May 20, 2023

and here is where I got to image

I added a few more attributed such as running state and canister empty/ok

How did you get the canister and running state?
thanks again all of you.

@ppastur
Copy link

ppastur commented May 21, 2023

I modified sensor.py in the section where the response from the API call is being mapped into attributes (I think) here
self._headers = {"Content-Type": "application/json; charset=utf-8", "Connection": "keep-alive", "Accept": "*/*", ``"Authorization" : self._id_token}
response = requests.get(url, headers = self._headers)
if response.status_code == 200:

and added the following lines;
self._canister = data["state"]["reported"]["equipment"]["robot"]["canister"]
self._attributes['canister'] = self._canister
self._running = data["state"]["reported"]["equipment"]["robot"]["state"]
self._attributes['running'] = self._running

Then I created template sensors in the config.yaml to map 0/1 to empty/full or running/Idle

Then in the card, I created badges and animations to show when running/idle or when the canister needs emptying.

Couldnt have done it without the code from @galletn. Its a shame I don't know how to help make this an official component of the integration to help make it easier for others who might like to add this and save the many hours/days to figure it out.

The next part id like to start working on is executing commands from the card like lift or start cycle or change cycle but I think I need either a little help with figuring out how do that or need many more hours to study how to reverse engineer the ios app - I only dabble :)

poolrobot.1.HB_proc.mp4

@LOki61
Copy link

LOki61 commented May 21, 2023

I modified sensor.py in the section where the response from the API call is being mapped into attributes (I think) here self._headers = {"Content-Type": "application/json; charset=utf-8", "Connection": "keep-alive", "Accept": "*/*","Authorization" : self._id_token} `` response = requests.get(url, headers = self._headers) `if response.status_code == 200:`

and added the following lines; self._canister = data["state"]["reported"]["equipment"]["robot"]["canister"] self._attributes['canister'] = self._canister self._running = data["state"]["reported"]["equipment"]["robot"]["state"] self._attributes['running'] = self._running

Then I created template sensors in the config.yaml to map 0/1 to empty/full or running/Idle

Then in the card, I created badges and animations to show when running/idle or when the canister needs emptying.

Couldnt have done it without the code from @galletn. Its a shame I don't know how to help make this an official component of the integration to help make it easier for others who might like to add this and save the many hours/days to figure it out.

The next part id like to start working on is executing commands from the card like lift or start cycle or change cycle but I think I need either a little help with figuring out how do that or need many more hours to study how to reverse engineer the ios app - I only dabble :)

poolrobot.1.HB_proc.mp4

Perhaps I can investigate, I am a complete noob. Can you tell me what I should download to review the API or code? How can I look at it. Maybe can tinker and learn.

@ppastur
Copy link

ppastur commented May 22, 2023

I would start with this : https://github.com/tekkamanendless/iaqualink . The part that I think will help is this : https://github.com/tekkamanendless/iaqualink#development. Once we understand how to structure the post and manually send commands via postman then we can progress.

@galletn
Copy link

galletn commented May 22, 2023

I'll have a look to make a separate integration out of this somewhere this week, then we can commit and do whatever we need to make it work for all of us. @ppastur indeed, that is what should be done, but need to find the time to install the proxy stuff, I already have a proxy running so I think that just wiresharking on that one might work too. Keep you posted!

@ppastur
Copy link

ppastur commented May 22, 2023

@galletn , I setup mitmproxy and managed to capture turning the robot on and off. It looks like its all websocket traffic which means Im a little out of my depth. I am however happy to work with you to provide you with the capture and also to test if that is helpful?

Here is the redacted websocket messages. Ive replaced userID, robot serial number and other serial/part numbers

SEND-->

{
    "action": "subscribe",
    "namespace": "authorization",
    "payload": {
        "userId": $USERID$
    },
    "service": "Authorization",
    "target": "$ROBOTSERIALNUMBER$",
    "version": 1
}

RECIEVE <--

{
    "namespace": "authorization",
    "payload": {
        "data": [
            {
                "accelero": [
                    -85,
                    -31,
                    1049
                ],
                "angleRotation": 183,
                "cleanerPos": 1,
                "cumulAngleRotation": 502,
                "cycleId": 1684646687,
                "floorBlockageCnt": 0,
                "gyro": [
                    1,
                    -2,
                    1
                ],
                "iPump": 2442,
                "iTract1": 99,
                "iTract2": 109,
                "lastMoveLength": 13,
                "loopCnt": 200,
                "magneto": [
                    0,
                    0,
                    0
                ],
                "movementId": 1,
                "patternId": 0,
                "pwmPump": 100,
                "pwmTract1": 80,
                "pwmTract2": 80,
                "stairsCnt": 1764,
                "tiltCnt": 32692,
                "timestamp": 1684650932,
                "totalHours": 348,
                "vEbox": 28,
                "vRobot": 28,
                "vSensor": 11,
                "wallCnt": 1660
            }
        ],
        "ota": {
            "status": "UP_TO_DATE"
        },
        "robot": {
            "metadata": {
                "desired": {
                    "equipment": {
                        "robot": {}
                    }
                },
                "reported": {
                    "aws": {
                        "session_id": {
                            "timestamp": 1684751732
                        },
                        "status": {
                            "timestamp": 1684751732
                        },
                        "timestamp": {
                            "timestamp": 1684751732
                        }
                    },
                    "dt": {
                        "timestamp": 1681926072
                    },
                    "eboxData": {
                        "completeCleanerPn": {
                            "timestamp": 1681926072
                        },
                        "completeCleanerSn": {
                            "timestamp": 1681926072
                        },
                        "controlBoxPn": {
                            "timestamp": 1681926072
                        },
                        "controlBoxSn": {
                            "timestamp": 1681926072
                        },
                        "motorBlockSn": {
                            "timestamp": 1681926072
                        },
                        "powerSupplySn": {
                            "timestamp": 1681926072
                        },
                        "sensorBlockSn": {
                            "timestamp": 1681926072
                        }
                    },
                    "equipment": {
                        "robot": {
                            "canister": {
                                "timestamp": 1684571511
                            },
                            "customCyc": {
                                "timestamp": 1681926072
                            },
                            "customIntensity": {
                                "timestamp": 1681926072
                            },
                            "cycleStartTime": {
                                "timestamp": 1684752278
                            },
                            "durations": {
                                "customTim": {
                                    "timestamp": 1681926072
                                },
                                "deepTim": {
                                    "timestamp": 1681926072
                                },
                                "firstSmartTim": {
                                    "timestamp": 1681926072
                                },
                                "quickTim": {
                                    "timestamp": 1681926072
                                },
                                "smartTim": {
                                    "timestamp": 1681926072
                                },
                                "waterTim": {
                                    "timestamp": 1681926072
                                }
                            },
                            "equipmentId": {
                                "timestamp": 1681926073
                            },
                            "errorCode": {
                                "timestamp": 1681926072
                            },
                            "errorState": {
                                "timestamp": 1681926072
                            },
                            "firstSmrtFlag": {
                                "timestamp": 1681926072
                            },
                            "liftControl": {
                                "timestamp": 1681926072
                            },
                            "logger": {
                                "timestamp": 1681926072
                            },
                            "prCyc": {
                                "timestamp": 1684752605
                            },
                            "repeat": {
                                "timestamp": 1681926072
                            },
                            "rmt_ctrl": {
                                "timestamp": 1681926072
                            },
                            "scanTimeDuration": {
                                "timestamp": 1681926072
                            },
                            "schConf0Enable": {
                                "timestamp": 1681926072
                            },
                            "schConf0Hour": {
                                "timestamp": 1681926072
                            },
                            "schConf0Min": {
                                "timestamp": 1681926072
                            },
                            "schConf0Prt": {
                                "timestamp": 1681926072
                            },
                            "schConf0WDay": {
                                "timestamp": 1681926072
                            },
                            "schConf1Enable": {
                                "timestamp": 1681926072
                            },
                            "schConf1Hour": {
                                "timestamp": 1681926072
                            },
                            "schConf1Min": {
                                "timestamp": 1681926072
                            },
                            "schConf1Prt": {
                                "timestamp": 1681926072
                            },
                            "schConf1WDay": {
                                "timestamp": 1681926072
                            },
                            "schConf2Enable": {
                                "timestamp": 1681926072
                            },
                            "schConf2Hour": {
                                "timestamp": 1681926072
                            },
                            "schConf2Min": {
                                "timestamp": 1681926072
                            },
                            "schConf2Prt": {
                                "timestamp": 1681926072
                            },
                            "schConf2WDay": {
                                "timestamp": 1681926072
                            },
                            "schConf3Enable": {
                                "timestamp": 1681926072
                            },
                            "schConf3Hour": {
                                "timestamp": 1681926072
                            },
                            "schConf3Min": {
                                "timestamp": 1681926072
                            },
                            "schConf3Prt": {
                                "timestamp": 1681926072
                            },
                            "schConf3WDay": {
                                "timestamp": 1681926072
                            },
                            "schConf4Enable": {
                                "timestamp": 1681926072
                            },
                            "schConf4Hour": {
                                "timestamp": 1681926072
                            },
                            "schConf4Min": {
                                "timestamp": 1681926072
                            },
                            "schConf4Prt": {
                                "timestamp": 1681926072
                            },
                            "schConf4WDay": {
                                "timestamp": 1681926072
                            },
                            "schConf5Enable": {
                                "timestamp": 1681926072
                            },
                            "schConf5Hour": {
                                "timestamp": 1681926072
                            },
                            "schConf5Min": {
                                "timestamp": 1681926072
                            },
                            "schConf5Prt": {
                                "timestamp": 1681926072
                            },
                            "schConf5WDay": {
                                "timestamp": 1681926072
                            },
                            "schConf6Enable": {
                                "timestamp": 1681926072
                            },
                            "schConf6Hour": {
                                "timestamp": 1681926072
                            },
                            "schConf6Min": {
                                "timestamp": 1681926072
                            },
                            "schConf6Prt": {
                                "timestamp": 1681926072
                            },
                            "schConf6WDay": {
                                "timestamp": 1681926072
                            },
                            "sensors": {
                                "sns_1": {
                                    "state": {
                                        "timestamp": 1684752306
                                    },
                                    "type": {
                                        "timestamp": 1681926072
                                    }
                                },
                                "sns_2": {
                                    "state": {
                                        "timestamp": 1684752306
                                    },
                                    "type": {
                                        "timestamp": 1681926072
                                    }
                                },
                                "sns_3": {
                                    "state": {
                                        "timestamp": 1681926072
                                    },
                                    "type": {
                                        "timestamp": 1681926072
                                    }
                                }
                            },
                            "state": {
                                "timestamp": 1684752605
                            },
                            "stepper": {
                                "timestamp": 1681926072
                            },
                            "stepperAdjTime": {
                                "timestamp": 1681926072
                            },
                            "totalHours": {
                                "timestamp": 1684752280
                            },
                            "vr": {
                                "timestamp": 1681926073
                            }
                        }
                    },
                    "jobId": {
                        "timestamp": 1651189088
                    },
                    "sn": {
                        "timestamp": 1681926072
                    },
                    "vr": {
                        "timestamp": 1681926072
                    }
                }
            },
            "state": {
                "desired": {
                    "equipment": {
                        "robot": {}
                    }
                },
                "reported": {
                    "aws": {
                        "session_id": "7d0137d2-06bd-45f4-8be9-e3f503886d65",
                        "status": "connected",
                        "timestamp": 1684751732835
                    },
                    "dt": "vr",
                    "eboxData": {
                        "completeCleanerPn": "${some-part-number}",
                        "completeCleanerSn": "${some-serial-number}",
                        "controlBoxPn": "${some-part-number}",
                        "controlBoxSn": "${some-serial-number}",
                        "motorBlockSn": "${some-serial-number}",
                        "powerSupplySn": "${some-serial-number}",
                        "sensorBlockSn": ""
                    },
                    "equipment": {
                        "robot": {
                            "canister": 0,
                            "customCyc": 1,
                            "customIntensity": 0,
                            "cycleStartTime": 1684752276,
                            "durations": {
                                "customTim": 150,
                                "deepTim": 165,
                                "firstSmartTim": 150,
                                "quickTim": 75,
                                "smartTim": 111,
                                "waterTim": 45
                            },
                            "equipmentId": "JY21002990",
                            "errorCode": 0,
                            "errorState": 0,
                            "firstSmrtFlag": 0,
                            "liftControl": 0,
                            "logger": 0,
                            "prCyc": 1,
                            "repeat": 0,
                            "rmt_ctrl": 0,
                            "scanTimeDuration": 30,
                            "schConf0Enable": 0,
                            "schConf0Hour": 0,
                            "schConf0Min": 0,
                            "schConf0Prt": 1,
                            "schConf0WDay": 0,
                            "schConf1Enable": 0,
                            "schConf1Hour": 0,
                            "schConf1Min": 0,
                            "schConf1Prt": 1,
                            "schConf1WDay": 1,
                            "schConf2Enable": 0,
                            "schConf2Hour": 0,
                            "schConf2Min": 0,
                            "schConf2Prt": 1,
                            "schConf2WDay": 2,
                            "schConf3Enable": 0,
                            "schConf3Hour": 0,
                            "schConf3Min": 0,
                            "schConf3Prt": 1,
                            "schConf3WDay": 3,
                            "schConf4Enable": 0,
                            "schConf4Hour": 0,
                            "schConf4Min": 0,
                            "schConf4Prt": 1,
                            "schConf4WDay": 4,
                            "schConf5Enable": 0,
                            "schConf5Hour": 0,
                            "schConf5Min": 0,
                            "schConf5Prt": 1,
                            "schConf5WDay": 5,
                            "schConf6Enable": 0,
                            "schConf6Hour": 0,
                            "schConf6Min": 0,
                            "schConf6Prt": 1,
                            "schConf6WDay": 6,
                            "sensors": {
                                "sns_1": {
                                    "state": 0,
                                    "type": "temperature"
                                },
                                "sns_2": {
                                    "state": 0,
                                    "type": "pressure"
                                },
                                "sns_3": {
                                    "state": 0,
                                    "type": "compass"
                                }
                            },
                            "state": 0,
                            "stepper": 0,
                            "stepperAdjTime": 15,
                            "totalHours": 349,
                            "vr": "V32E47"
                        }
                    },
                    "jobId": "Job_VR_V32E47_V32C47",
                    "sn": "$ROBOTSERIALNUMBER$",
                    "vr": "V32C47"
                }
            },
            "timestamp": 1684752680,
            "version": 138294
        }
    },
    "service": "Authorization",
    "target": "$ROBOTSERIALNUMBER$"
}

SEND --> (start clean cycle on the app)

{
    "action": "setCleanerState",
    "namespace": "vr",
    "payload": {
        "clientToken": "$USERID$|Z6dmjtJcsJ79ANUfe1rYoh|cQ4zyywG4B2NSlv8PMpnZo",
        "state": {
            "desired": {
                "equipment": {
                    "robot": {
                        "state": 1
                    }
                }
            }
        }
    },
    "service": "StateController",
    "target": "$ROBOTSERIALNUMBER$",
    "version": 1
}

notice state:1

RECIEVE <-- (a bunch of these)

{
    "event": "StateReported",
    "payload": {
        "clientToken": "$USERID$|Z6dmjtJcsJ79ANUfe1rYoh|cQ4zyywG4B2NSlv8PMpnZo",
        "metadata": {
            "desired": {
                "equipment": {
                    "robot": {
                        "state": {
                            "timestamp": 1684752688
                        }
                    }
                }
            }
        },
        "state": {
            "desired": {
                "equipment": {
                    "robot": {
                        "state": 1
                    }
                }
            }
        },
        "timestamp": 1684752688,
        "version": 138295
    },
    "service": "StateStreamer",
    "target": "$ROBOTSERIALNUMBER$",
    "version": 1
}

SEND --> (stop clean cycle on the app)

{
    "action": "setCleanerState",
    "namespace": "vr",
    "payload": {
        "clientToken": "$USERID$|Z6dmjtJcsJ79ANUfe1rYoh|8RhttxQIeSlg1q1nPj0xoe",
        "state": {
            "desired": {
                "equipment": {
                    "robot": {
                        "state": 0
                    }
                }
            }
        }
    },
    "service": "StateController",
    "target": "$ROBOTSERIALNUMBER$",
    "version": 1
}

notice state: 0

RECIEVE <-- (a bunch of these)

{
    "event": "StateReported",
    "payload": {
        "clientToken": "$USERID$|Z6dmjtJcsJ79ANUfe1rYoh|8RhttxQIeSlg1q1nPj0xoe",
        "metadata": {
            "desired": {
                "equipment": {
                    "robot": {
                        "state": {
                            "timestamp": 1684752705
                        }
                    }
                }
            }
        },
        "state": {
            "desired": {
                "equipment": {
                    "robot": {
                        "state": 0
                    }
                }
            }
        },
        "timestamp": 1684752705,
        "version": 138300
    },
    "service": "StateStreamer",
    "target": "$ROBOTSERIALNUMBER$",
    "version": 1
}

@galletn
Copy link

galletn commented May 22, 2023

I guess we can move to https://github.com/galletn/iaqualink prepping it to get into HACS now

@LOki61
Copy link

LOki61 commented May 23, 2023

I guess we can move to https://github.com/galletn/iaqualink prepping it to get into HACS now

How can I help guys?

@galletn
Copy link

galletn commented May 23, 2023

@ppastur @LOki61 please join the converstation here:

galletn/iaqualink#1

@ppastur can you repost your proxy logs there? also did you capture the URL's that were triggered? can you also post the changes you made to the code to make it work for you? I'll have a look to make it generic for all robots.

@LOki61 you could help by sending your changes too, I'll also try to fit these in. Then we have a nice clean start for all. If you could also try the HACS install? For me it worked but ... better double check 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

6 participants