picklepete / pyicloud

A Python + iCloud wrapper to access iPhone and Calendar data.
MIT License
2.5k stars 444 forks source link

Specific device polling #142

Open AaronLionsheep opened 7 years ago

AaronLionsheep commented 7 years ago

If I do api.devices[0].location() will that only request the location for that device or will it end up telling all of my devices to send their location back to iCloud? I currently have a script polling an iPhone every 30 seconds for testing, but I noticed that my Apple Watch battery has drained significantly more than a normal day.

torarnv commented 6 years ago

Yes, the way things work right now is that calling location() will result in a call to FindMyiPhoneServiceManager.refresh_client(), which passes selectedDevice: all in the request.

I don't know what format selectedDevice takes, but you could look at the network request in Chrome and figure that out, and then e.g. add a deviced = all argument to refresh_client.

walthowd commented 6 years ago

Would love to see this resolved, Home Assistant uses pyicloud for presence detection and the fact that all devices are polled causes battery drain for a large number of users.

coddingtonbear commented 6 years ago

It wouldn't take a very large effort to figure out the format following the instructions above; maybe you could post a pull request adding this feature, @walthowd?

northtree commented 6 years ago

I have changed the selectedDevice param. However, iCloud still returns all devices information.

diff --git a/pyicloud/services/findmyiphone.py b/pyicloud/services/findmyiphone.py

-    def refresh_client(self):
+    def refresh_client(self, device_id='all'):

-                        'selectedDevice': 'all',
+                        # 'selectedDevice': 'all',
+                        'selectedDevice': device_id,

     def location(self):
-        self.manager.refresh_client()
+        self.manager.refresh_client(device_id=self.content['id'])
         return self.content['location']
northtree commented 6 years ago

I have also tried to capture packets through iCould website via Charles. It looks like iCloud always return all devices information and ignore the selectedDevice parameter.

1. Refresh on all devices screen shot 2018-05-22 at 3 24 02 pm

2. Refresh on one devices screen shot 2018-05-22 at 3 24 20 pm

asherkin commented 6 years ago

selectedDevice is only respected for refreshClient, not initClient.

northtree commented 6 years ago

@asherkin I was discussing about refreshClient.

dsouzarc commented 5 years ago

Any luck/update with this? Using the Find iPhone app, it seems like all devices' locations are returned even when clicking one device and pressing the refresh button for that specific device

coddingtonbear commented 5 years ago

I'm afraid that this library is built entirely upon reverse-engineering how iCloud works; it's not likely to make much progress without investigation and further research by folks like you who are affected by the issue.

dsouzarc commented 5 years ago

I'll try it out; I've always had SSL issues when using Charles on my Mac to do a MITM attack from using iCloud services from my iPhone (even though I added the Charles SSL certificate to my iPhone and enabled SSL Proxying for all URLs), but maybe I should have tried to do it from my Mac? What's the best way/approach you've found?