-
Notifications
You must be signed in to change notification settings - Fork 20
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
Comments
this project looks interesting |
I don't have one of those so unless this changes, I won't be working on adding support. Happy to review patches though! |
|
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?). |
@galletn how about we create a new integration just for the robots ? I would be happy to help |
hello! yes, that would be fine, I have a polaris and could help in whatever is needed. |
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. |
If you already want to test the basics, this should read out your robot. add the extracted folder to your custom components folder. |
thanks @galletn!
directly in configuration.yaml? gives the following error Registrar: homeassistant.setup |
I have already managed to make it appear as an entity within home assistant. |
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? |
thank you @galletn |
Sorry it took some time, but please find the postman collection included. I put $ where you should change some values. |
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?? |
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×tamp=1683565854) and passes three values. User_id, signature and Timestamp. These last two I think are calculated somehow? |
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 :( |
@bertocea85 I used "RefreshToken" as the $AuthKey I received on login. I also changed the URL in GetDeviceFeatures to be; Where XXXMYSERIALNUMBERXXX=my robot serial number reported from the login stage. I mention this because the original postman collection indicated I added the extracted folder (iaqualink.zip) to my custom components folder. I added the following to my config.yaml: What have I missed? |
I understand that the iaqualink folder is inside custom_components (custom_components/iaqualink/xx.py).
And in configuration.yaml at the end of the file: |
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 |
Ok - I figured it out. I had to modify sensor.py. line 110 is trying to map
|
I modified sensor.py in the section where the response from the API call is being mapped into attributes (I think) here and added the following lines; 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. |
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. |
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 , 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
} |
I guess we can move to https://github.com/galletn/iaqualink prepping it to get into HACS now |
How can I help guys? |
@ppastur @LOki61 please join the converstation here: @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 👍 |
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?
The text was updated successfully, but these errors were encountered: