Advertisement
Bart274

icloud.py

Feb 29th, 2016
837
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 5.65 KB | None | 0 0
  1. """
  2. homeassistant.components.device_tracker.icloud
  3. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  4. Device tracker platform that supports scanning iCloud devices.
  5.  
  6. For more details about this platform, please refer to the documentation at
  7. https://home-assistant.io/components/device_tracker.icloud/
  8. """
  9. import logging
  10.  
  11. import re
  12. from homeassistant.const import CONF_USERNAME, CONF_PASSWORD, CONF_NAME
  13. from homeassistant.helpers.event import track_utc_time_change
  14.  
  15. _LOGGER = logging.getLogger(__name__)
  16.  
  17. REQUIREMENTS = ['pyicloud==0.7.2']
  18.  
  19. CONF_INTERVAL = 'interval'
  20. DEFAULT_INTERVAL = 8
  21.  
  22. # entity attributes
  23. ATTR_USERNAME = 'username'
  24. ATTR_PASSWORD = 'password'
  25. ATTR_ACCOUNTNAME = 'accountname'
  26.  
  27. ICLOUDTRACKERS = {}
  28.  
  29.  
  30. def setup_scanner(hass, config, see):
  31.     """ Set up the iCloud Scanner. """
  32.  
  33.     # Get the username and password from the configuration
  34.     username = config.get(CONF_USERNAME)
  35.     password = config.get(CONF_PASSWORD)
  36.     name = config.get(CONF_NAME, username)
  37.  
  38.     iclouddevice = Icloud(hass, username, password, name)
  39.     ICLOUDTRACKERS[name] = iclouddevice
  40.  
  41.     def lost_iphone(call):
  42.         """ Calls the lost iphone function if the device is found """
  43.         accountname = call.data.get('accountname')
  44.         devicename = call.data.get('devicename')
  45.         if accountname in ICLOUDTRACKERS:
  46.             ICLOUDTRACKERS[accountname].lost_iphone(devicename)
  47.  
  48.     hass.services.register('device_tracker', 'lost_iphone',
  49.                            lost_iphone)
  50.  
  51.     def update_icloud(call):
  52.         """ Calls the update function of an icloud account """
  53.         accountname = call.data.get('accountname')
  54.         if accountname in ICLOUDTRACKERS:
  55.             ICLOUDTRACKERS[accountname].update_icloud(see)
  56.            
  57.     def keep_alive(now):
  58.         """ Keeps the api logged in of all account """
  59.         for accountname in ICLOUDTRACKERS:
  60.             ICLOUDTRACKERS[accountname].keep_alive()
  61.  
  62.     hass.services.register('device_tracker',
  63.                            'update_icloud', update_icloud)
  64.     iclouddevice.update_icloud(see)
  65.  
  66.     track_utc_time_change(
  67.         hass, iclouddevice.update_icloud,
  68.         minute=range(0, 60, config.get(CONF_INTERVAL, DEFAULT_INTERVAL)),
  69.         second=0
  70.     )
  71.    
  72.     track_utc_time_change(
  73.         hass, keep_alive,
  74.         second=0
  75.     )
  76.    
  77.     return True
  78.  
  79.  
  80. class Icloud(object):  # pylint: disable=too-many-instance-attributes
  81.     """ Represents a Proximity in Home Assistant. """
  82.     def __init__(self, hass, username, password, name):
  83.         # pylint: disable=too-many-arguments
  84.         from pyicloud import PyiCloudService
  85.         from pyicloud.exceptions import PyiCloudFailedLoginException
  86.  
  87.         self.hass = hass
  88.         self.username = username
  89.         self.password = password
  90.         self.accountname = name
  91.         self.api = None
  92.  
  93.         if self.username is None or self.password is None:
  94.             _LOGGER.error('Must specify a username and password')
  95.         else:
  96.             try:
  97.                 _LOGGER.info('Logging into iCloud Account')
  98.                 # Attempt the login to iCloud
  99.                 self.api = PyiCloudService(self.username,
  100.                                            self.password,
  101.                                            verify=True)
  102.             except PyiCloudFailedLoginException as error:
  103.                 _LOGGER.exception('Error logging into iCloud Service: %s',
  104.                                   error)
  105.  
  106.     @property
  107.     def state(self):
  108.         """ returns the state of the icloud tracker """
  109.         return self.api is not None
  110.  
  111.     @property
  112.     def state_attributes(self):
  113.         """ returns the friendlyname of the icloud tracker """
  114.         return {
  115.             ATTR_ACCOUNTNAME: self.accountname
  116.         }
  117.        
  118.     def keep_alive(self):
  119.         """ Keeps the api alive """
  120.         if self.api is not None:
  121.             self.api.authenticate()
  122.  
  123.     def lost_iphone(self, devicename):
  124.         """ Calls the lost iphone function if the device is found """
  125.         if self.api is not None:
  126.             self.api.authenticate()
  127.             for device in self.api.devices:
  128.                 status = device.status()
  129.                 if devicename is None or devicename == status['name']:
  130.                     device.play_sound()
  131.  
  132.     def update_icloud(self, see):
  133.         """ Authenticate against iCloud and scan for devices. """
  134.         if self.api is not None:
  135.             from pyicloud.exceptions import PyiCloudNoDevicesException
  136.  
  137.             try:
  138.                 # The session timeouts if we are not using it so we
  139.                 # have to re-authenticate. This will send an email.
  140.                 self.api.authenticate()
  141.                 # Loop through every device registered with the iCloud account
  142.                 for device in self.api.devices:
  143.                     status = device.status()
  144.                     location = device.location()
  145.                     if location:
  146.                         see(
  147.                             dev_id=re.sub(r"(\s|\W|')",
  148.                                           '',
  149.                                           status['name']),
  150.                             host_name=status['name'],
  151.                             gps=(location['latitude'], location['longitude']),
  152.                             battery=status['batteryLevel']*100,
  153.                             gps_accuracy=location['horizontalAccuracy']
  154.                         )
  155.                     else:
  156.                         # No location found for the device so continue
  157.                         continue
  158.             except PyiCloudNoDevicesException:
  159.                 _LOGGER.info('No iCloud Devices found!')
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement