iaqualink-py icon indicating copy to clipboard operation
iaqualink-py copied to clipboard

Missing support for vr systems (vacuum)

Open johntdyer opened this issue 3 years ago • 31 comments

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 avatar Sep 22 '22 00:09 johntdyer

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

johntdyer avatar Sep 22 '22 18:09 johntdyer

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

Happy to review patches though!

flz avatar Oct 17 '22 16:10 flz

Hi Guys,

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

image

galletn avatar Apr 14 '23 15:04 galletn

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

galletn avatar Apr 14 '23 15:04 galletn

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?).

flz avatar Apr 14 '23 18:04 flz

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

johntdyer avatar Apr 14 '23 20:04 johntdyer

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

bertocea85 avatar Apr 20 '23 18:04 bertocea85

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 avatar Apr 26 '23 10:04 galletn

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

galletn avatar Apr 26 '23 10:04 galletn

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 avatar Apr 26 '23 13:04 bertocea85

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

bertocea85 avatar Apr 26 '23 14:04 bertocea85

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?

galletn avatar Apr 27 '23 07:04 galletn

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.

bertocea85 avatar Apr 28 '23 11:04 bertocea85

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

galletn avatar May 12 '23 19:05 galletn

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.

ppastur avatar May 19 '23 08:05 ppastur

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?

bertocea85 avatar May 19 '23 10:05 bertocea85

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 avatar May 19 '23 13:05 ppastur

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

ppastur avatar May 19 '23 13:05 ppastur

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.

bertocea85 avatar May 19 '23 17:05 bertocea85

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 avatar May 20 '23 05:05 ppastur

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 avatar May 20 '23 08:05 ppastur

and here is where I got to image

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

ppastur avatar May 20 '23 13:05 ppastur

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.

LOki61 avatar May 20 '23 22:05 LOki61

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

https://github.com/flz/iaqualink-py/assets/91765182/950c3478-9fc8-4a1b-b9dd-6977317f75d9

ppastur avatar May 21 '23 02:05 ppastur

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.

LOki61 avatar May 21 '23 16:05 LOki61

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.

ppastur avatar May 22 '23 00:05 ppastur

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!

galletn avatar May 22 '23 05:05 galletn

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

ppastur avatar May 22 '23 12:05 ppastur

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

galletn avatar May 22 '23 19:05 galletn

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

How can I help guys?

LOki61 avatar May 23 '23 00:05 LOki61