{"action":"created","comment":{"url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/comments/84017016","pull_request_review_id":4820687,"id":84017016,"diff_hunk":"@@ -0,0 +1,993 @@\n+\"\"\"\n+homeassistant.components.icloud\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+Platform that supports scanning iCloud.\n+\n+For more details about this platform, please refer to the documentation at\n+https://home-assistant.io/components/icloud/\n+\"\"\"\n+import logging\n+import time as time\n+from datetime import datetime, timezone, timedelta\n+from pytz import timezone\n+import pytz\n+from math import floor\n+import random\n+\n+from pyicloud import PyiCloudService\n+from pyicloud.exceptions import PyiCloudFailedLoginException\n+\n+import re\n+from homeassistant.const import CONF_USERNAME, CONF_PASSWORD, CONF_NAME\n+from homeassistant.helpers.entity import Entity\n+from homeassistant.helpers.entity import generate_entity_id\n+from homeassistant.components.device_tracker import see\n+from homeassistant.helpers.event import track_state_change\n+from homeassistant.helpers.event import track_time_change\n+from homeassistant.helpers.event import track_point_in_time\n+from homeassistant.helpers.event import track_utc_time_change\n+import homeassistant.util.dt as dt_util\n+from homeassistant.util.location import distance\n+\n+_LOGGER = logging.getLogger(__name__)\n+\n+REQUIREMENTS = ['pyicloud==0.9.1']\n+\n+DEPENDENCIES = ['zone', 'device_tracker']\n+\n+CONF_EVENTS = 'events'\n+DEFAULT_EVENTS = False\n+\n+CONF_COOKIEDIRECTORY = 'cookiedirectory'\n+\n+# entity attributes\n+ATTR_ACCOUNTNAME = 'accountname'\n+ATTR_INTERVAL = 'interval'\n+ATTR_DEVICENAME = 'devicename'\n+ATTR_BATTERY = 'battery'\n+ATTR_DISTANCE = 'distance'\n+ATTR_STARTTIME = 'start_time'\n+ATTR_ENDTIME = 'end_time'\n+ATTR_DURATION = 'duration'\n+ATTR_REMAINING = 'remaining_time'\n+ATTR_DEVICESTATUS = 'device_status'\n+ATTR_LOWPOWERMODE = 'low_power_mode'\n+ATTR_BATTERYSTATUS = 'battery_status'\n+ATTR_LOCATION = 'location'\n+ATTR_FRIENDLY_NAME = 'friendly_name'\n+ATTR_GOOGLE_MAPS_TRAVEL_TIME = 'google_maps_travel_time'\n+ATTR_GOOGLE_MAPS_TRAVEL_TIME_DURATION = 'gmtt_duration'\n+ATTR_GOOGLE_MAPS_TRAVEL_TIME_ORIGIN = 'gmtt_origin'\n+\n+TYPE_CURRENT = 'currentevent'\n+TYPE_NEXT = 'nextevent'\n+\n+ICLOUDTRACKERS = {}\n+\n+DOMAIN = 'icloud'\n+DOMAIN2 = 'idevice'\n+DOMAIN3 = 'ievent'\n+\n+ENTITY_ID_FORMAT_ICLOUD = DOMAIN + '.{}'\n+ENTITY_ID_FORMAT_DEVICE = DOMAIN2 + '.{}'\n+ENTITY_ID_FORMAT_EVENT = DOMAIN3 + '.{}'\n+\n+DEVICESTATUSSET = ['features', 'maxMsgChar', 'darkWake', 'fmlyShare',\n+                   'deviceStatus', 'remoteLock', 'activationLocked',\n+                   'deviceClass', 'id', 'deviceModel', 'rawDeviceModel',\n+                   'passcodeLength', 'canWipeAfterLock', 'trackingInfo',\n+                   'location', 'msg', 'batteryLevel', 'remoteWipe',\n+                   'thisDevice', 'snd', 'prsId', 'wipeInProgress',\n+                   'lowPowerMode', 'lostModeEnabled', 'isLocating',\n+                   'lostModeCapable', 'mesg', 'name', 'batteryStatus',\n+                   'lockedTimestamp', 'lostTimestamp', 'locationCapable',\n+                   'deviceDisplayName', 'lostDevice', 'deviceColor',\n+                   'wipedTimestamp', 'modelDisplayName', 'locationEnabled',\n+                   'isMac', 'locFoundEnabled']\n+\n+\n+def setup(hass, config):\n+    \"\"\" Set up the iCloud Scanner. \"\"\"\n+\n+    if config.get(DOMAIN) is None:\n+        return False\n+\n+    for account, account_config in config[DOMAIN].items():\n+\n+        if not isinstance(account_config, dict):\n+            _LOGGER.error(\"Missing configuration data for account %s\", account)\n+            continue\n+\n+        if CONF_USERNAME not in account_config:\n+            _LOGGER.error(\"Missing username for account %s\", account)\n+            continue\n+\n+        if CONF_PASSWORD not in account_config:\n+            _LOGGER.error(\"Missing password for account %s\", account)\n+            continue\n+\n+        # Get the username and password from the configuration\n+        username = account_config.get(CONF_USERNAME)\n+        password = account_config.get(CONF_PASSWORD)\n+        cookiedirectory = account_config.get(CONF_COOKIEDIRECTORY, None)\n+\n+        ignored_devices = []\n+        if 'ignored_devices' in account_config:\n+            ignored_dev = account_config.get('ignored_devices')\n+            for each_dev in ignored_dev:\n+                ignored_devices.append(each_dev)\n+\n+        getevents = account_config.get(CONF_EVENTS, DEFAULT_EVENTS)\n+\n+        googletraveltime = {}\n+        if 'googletraveltime' in account_config:\n+            gttconfig = account_config.get('googletraveltime')\n+            for google, googleconfig in gttconfig.items():\n+                googletraveltime[google] = googleconfig\n+\n+        icloudaccount = Icloud(hass, username, password, cookiedirectory,\n+                               account, ignored_devices, getevents,\n+                               googletraveltime)\n+        icloudaccount.update_ha_state()\n+        ICLOUDTRACKERS[account] = icloudaccount\n+        if ICLOUDTRACKERS[account].api is not None:\n+            for device in ICLOUDTRACKERS[account].devices:\n+                iclouddevice = ICLOUDTRACKERS[account].devices[device]\n+                devicename = iclouddevice.devicename.lower()\n+                track_state_change(hass,\n+                                   'device_tracker.' + devicename,\n+                                   iclouddevice.devicechanged)\n+\n+        if 'manual_update' in account_config:\n+            def update_now(now):\n+                ICLOUDTRACKERS[account].update_icloud(see)\n+\n+            manual_update = account_config.get('manual_update')\n+            for each_time in manual_update:\n+                each_time = dt_util.parse_time(each_time)\n+                track_time_change(hass, update_now,\n+                                  hour=each_time.hour,\n+                                  minute=each_time.minute,\n+                                  second=each_time.second)\n+\n+    if not ICLOUDTRACKERS:\n+        _LOGGER.error(\"No ICLOUDTRACKERS added\")\n+        return False\n+\n+    randomseconds = random.randint(10, 59)\n+\n+    def lost_iphone(call):\n+        \"\"\" Calls the lost iphone function if the device is found \"\"\"\n+        accountname = call.data.get('accountname')\n+        devicename = call.data.get('devicename')\n+        if accountname is None:\n+            for account in ICLOUDTRACKERS:\n+                ICLOUDTRACKERS[account].lost_iphone(devicename)\n+        elif accountname in ICLOUDTRACKERS:\n+            ICLOUDTRACKERS[accountname].lost_iphone(devicename)\n+\n+    hass.services.register(DOMAIN, 'lost_iphone',\n+                           lost_iphone)\n+\n+    def update_icloud(call):\n+        \"\"\" Calls the update function of an icloud account \"\"\"\n+        accountname = call.data.get('accountname')\n+        devicename = call.data.get('devicename')\n+        if accountname is None:\n+            for account in ICLOUDTRACKERS:\n+                ICLOUDTRACKERS[account].update_icloud(see, devicename)\n+        elif accountname in ICLOUDTRACKERS:\n+            ICLOUDTRACKERS[accountname].update_icloud(see, devicename)\n+    hass.services.register(DOMAIN,\n+                           'update_icloud', update_icloud)\n+\n+    def keep_alive(now):\n+        \"\"\" Keeps the api logged in of all account \"\"\"\n+        for accountname in ICLOUDTRACKERS:\n+            try:\n+                ICLOUDTRACKERS[accountname].keep_alive()\n+            except ValueError:\n+                _LOGGER.error(\"something went wrong for account %s, \" +\n+                             \"retrying in a minute\", accountname)\n+\n+    track_utc_time_change(\n+        hass, keep_alive,\n+        second=randomseconds\n+    )\n+\n+    def setinterval(call):\n+        \"\"\" Calls the update function of an icloud account \"\"\"\n+        accountname = call.data.get('accountname')\n+        interval = call.data.get('interval')\n+        devicename = call.data.get('devicename')\n+        if accountname is None:\n+            for account in ICLOUDTRACKERS:\n+                ICLOUDTRACKERS[account].setinterval(interval, devicename)\n+        elif accountname in ICLOUDTRACKERS:\n+            ICLOUDTRACKERS[accountname].setinterval(interval, devicename)\n+\n+    hass.services.register(DOMAIN,\n+                           'setinterval', setinterval)\n+\n+    # Tells the bootstrapper that the component was successfully initialized\n+    return True\n+\n+class IDevice(Entity):  # pylint: disable=too-many-instance-attributes\n+    \"\"\" Represents a Proximity in Home Assistant. \"\"\"\n+    def __init__(self, hass, icloudobject, name, identifier, googletraveltime):\n+        # pylint: disable=too-many-arguments\n+        self.hass = hass\n+        self.icloudobject = icloudobject\n+        self.devicename = name\n+        self.identifier = identifier\n+        self._request_interval_seconds = 60\n+        self._interval = 1\n+        self.api = icloudobject.api\n+        self._distance = None\n+        self._battery = None\n+        self._overridestate = None\n+        self._devicestatuscode = None\n+        self._devicestatus = None\n+        self._lowPowerMode = None\n+        self._batteryStatus = None\n+        self._googletraveltime = googletraveltime\n+        self._gttduration = None\n+        self._gttorigin = None\n+\n+        self.entity_id = generate_entity_id(\n+            ENTITY_ID_FORMAT_DEVICE, self.devicename,\n+            hass=self.hass)\n+\n+    @property\n+    def state(self):\n+        \"\"\" returns the state of the icloud tracker \"\"\"\n+        return self._interval\n+\n+    @property\n+    def unit_of_measurement(self):","path":"homeassistant/components/icloud.py","position":247,"original_position":247,"commit_id":"b849d04b1d11fdf190fa41017a204a2c195d72dc","original_commit_id":"b849d04b1d11fdf190fa41017a204a2c195d72dc","user":{"login":"balloobbot","id":16367972,"avatar_url":"https://avatars.githubusercontent.com/u/16367972?v=3","gravatar_id":"","url":"https://api.github.com/users/balloobbot","html_url":"https://github.com/balloobbot","followers_url":"https://api.github.com/users/balloobbot/followers","following_url":"https://api.github.com/users/balloobbot/following{/other_user}","gists_url":"https://api.github.com/users/balloobbot/gists{/gist_id}","starred_url":"https://api.github.com/users/balloobbot/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/balloobbot/subscriptions","organizations_url":"https://api.github.com/users/balloobbot/orgs","repos_url":"https://api.github.com/users/balloobbot/repos","events_url":"https://api.github.com/users/balloobbot/events{/privacy}","received_events_url":"https://api.github.com/users/balloobbot/received_events","type":"User","site_admin":false},"body":"_[farcy v1.1](https://github.com/appfolio/farcy)_\n* D210: No whitespaces allowed surrounding docstring text\n* D400: First line should end with a period (not 'y')","created_at":"2016-10-19T08:13:27Z","updated_at":"2016-10-19T08:13:27Z","html_url":"https://github.com/home-assistant/home-assistant/pull/3946#discussion_r84017016","pull_request_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3946","_links":{"self":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/comments/84017016"},"html":{"href":"https://github.com/home-assistant/home-assistant/pull/3946#discussion_r84017016"},"pull_request":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3946"}}},"pull_request":{"url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3946","id":89960526,"html_url":"https://github.com/home-assistant/home-assistant/pull/3946","diff_url":"https://github.com/home-assistant/home-assistant/pull/3946.diff","patch_url":"https://github.com/home-assistant/home-assistant/pull/3946.patch","issue_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/3946","number":3946,"state":"open","locked":false,"title":"change icloud device_tracker into new platform","user":{"login":"Bart274","id":1118630,"avatar_url":"https://avatars.githubusercontent.com/u/1118630?v=3","gravatar_id":"","url":"https://api.github.com/users/Bart274","html_url":"https://github.com/Bart274","followers_url":"https://api.github.com/users/Bart274/followers","following_url":"https://api.github.com/users/Bart274/following{/other_user}","gists_url":"https://api.github.com/users/Bart274/gists{/gist_id}","starred_url":"https://api.github.com/users/Bart274/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Bart274/subscriptions","organizations_url":"https://api.github.com/users/Bart274/orgs","repos_url":"https://api.github.com/users/Bart274/repos","events_url":"https://api.github.com/users/Bart274/events{/privacy}","received_events_url":"https://api.github.com/users/Bart274/received_events","type":"User","site_admin":false},"body":"**Description:**\r\nThis PR changes the old icloud device_tracker into a new platform.\r\nThis adds the following features to the new platform:\r\n- Each device has it's own dynamic interval instead of one fixed interval for all devices linked to one account\r\n- This adds the ability to ignore specific devices that you don't want to track, so their battery isn't drained\r\n- This adds the possiblity to view the events from your icloud calendar in HA\r\n- This adds the ability to update the devices on a fixed time no matter what the interval is at that time\r\n- This adds 3 new services: one to call the update manually once, one to play the lost iphone sound on a device and one to change the interval.\r\n\r\n**Example entry for `configuration.yaml` (if applicable):**\r\n```yaml\r\nicloud:\r\n  bart:\r\n    username: <my username>\r\n    password: <my password>\r\n    manual_update:\r\n      - '7:45'\r\n      - '8:00'\r\n      - '17:45'\r\n      - '18:00'\r\n    ignored_devices:\r\n      - iphonevanbvb\r\n      - ipodvanbart\r\n    googletraveltime:\r\n      iphonebart: sensor.bart_naar_huis\r\n    events: True\r\n  sharon:\r\n    username: <gf's username>\r\n    password: <gf's password>\r\n    manual_update:\r\n      - '8:45'\r\n      - '9:00'\r\n      - '18:45'\r\n      - '19:00'\r\n```","created_at":"2016-10-19T08:12:36Z","updated_at":"2016-10-19T08:13:28Z","closed_at":null,"merged_at":null,"merge_commit_sha":"c0339dff40a9484e1398a37951cc58d06a1d51b3","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3946/commits","review_comments_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3946/comments","review_comment_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/comments{/number}","comments_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/3946/comments","statuses_url":"https://api.github.com/repos/home-assistant/home-assistant/statuses/b849d04b1d11fdf190fa41017a204a2c195d72dc","head":{"label":"Bart274:new_icloud_platform","ref":"new_icloud_platform","sha":"b849d04b1d11fdf190fa41017a204a2c195d72dc","user":{"login":"Bart274","id":1118630,"avatar_url":"https://avatars.githubusercontent.com/u/1118630?v=3","gravatar_id":"","url":"https://api.github.com/users/Bart274","html_url":"https://github.com/Bart274","followers_url":"https://api.github.com/users/Bart274/followers","following_url":"https://api.github.com/users/Bart274/following{/other_user}","gists_url":"https://api.github.com/users/Bart274/gists{/gist_id}","starred_url":"https://api.github.com/users/Bart274/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Bart274/subscriptions","organizations_url":"https://api.github.com/users/Bart274/orgs","repos_url":"https://api.github.com/users/Bart274/repos","events_url":"https://api.github.com/users/Bart274/events{/privacy}","received_events_url":"https://api.github.com/users/Bart274/received_events","type":"User","site_admin":false},"repo":{"id":71329112,"name":"home-assistant","full_name":"Bart274/home-assistant","owner":{"login":"Bart274","id":1118630,"avatar_url":"https://avatars.githubusercontent.com/u/1118630?v=3","gravatar_id":"","url":"https://api.github.com/users/Bart274","html_url":"https://github.com/Bart274","followers_url":"https://api.github.com/users/Bart274/followers","following_url":"https://api.github.com/users/Bart274/following{/other_user}","gists_url":"https://api.github.com/users/Bart274/gists{/gist_id}","starred_url":"https://api.github.com/users/Bart274/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Bart274/subscriptions","organizations_url":"https://api.github.com/users/Bart274/orgs","repos_url":"https://api.github.com/users/Bart274/repos","events_url":"https://api.github.com/users/Bart274/events{/privacy}","received_events_url":"https://api.github.com/users/Bart274/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/Bart274/home-assistant","description":":house_with_garden: Open-source home automation platform running on Python 3","fork":true,"url":"https://api.github.com/repos/Bart274/home-assistant","forks_url":"https://api.github.com/repos/Bart274/home-assistant/forks","keys_url":"https://api.github.com/repos/Bart274/home-assistant/keys{/key_id}","collaborators_url":"https://api.github.com/repos/Bart274/home-assistant/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/Bart274/home-assistant/teams","hooks_url":"https://api.github.com/repos/Bart274/home-assistant/hooks","issue_events_url":"https://api.github.com/repos/Bart274/home-assistant/issues/events{/number}","events_url":"https://api.github.com/repos/Bart274/home-assistant/events","assignees_url":"https://api.github.com/repos/Bart274/home-assistant/assignees{/user}","branches_url":"https://api.github.com/repos/Bart274/home-assistant/branches{/branch}","tags_url":"https://api.github.com/repos/Bart274/home-assistant/tags","blobs_url":"https://api.github.com/repos/Bart274/home-assistant/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/Bart274/home-assistant/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/Bart274/home-assistant/git/refs{/sha}","trees_url":"https://api.github.com/repos/Bart274/home-assistant/git/trees{/sha}","statuses_url":"https://api.github.com/repos/Bart274/home-assistant/statuses/{sha}","languages_url":"https://api.github.com/repos/Bart274/home-assistant/languages","stargazers_url":"https://api.github.com/repos/Bart274/home-assistant/stargazers","contributors_url":"https://api.github.com/repos/Bart274/home-assistant/contributors","subscribers_url":"https://api.github.com/repos/Bart274/home-assistant/subscribers","subscription_url":"https://api.github.com/repos/Bart274/home-assistant/subscription","commits_url":"https://api.github.com/repos/Bart274/home-assistant/commits{/sha}","git_commits_url":"https://api.github.com/repos/Bart274/home-assistant/git/commits{/sha}","comments_url":"https://api.github.com/repos/Bart274/home-assistant/comments{/number}","issue_comment_url":"https://api.github.com/repos/Bart274/home-assistant/issues/comments{/number}","contents_url":"https://api.github.com/repos/Bart274/home-assistant/contents/{+path}","compare_url":"https://api.github.com/repos/Bart274/home-assistant/compare/{base}...{head}","merges_url":"https://api.github.com/repos/Bart274/home-assistant/merges","archive_url":"https://api.github.com/repos/Bart274/home-assistant/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/Bart274/home-assistant/downloads","issues_url":"https://api.github.com/repos/Bart274/home-assistant/issues{/number}","pulls_url":"https://api.github.com/repos/Bart274/home-assistant/pulls{/number}","milestones_url":"https://api.github.com/repos/Bart274/home-assistant/milestones{/number}","notifications_url":"https://api.github.com/repos/Bart274/home-assistant/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/Bart274/home-assistant/labels{/name}","releases_url":"https://api.github.com/repos/Bart274/home-assistant/releases{/id}","deployments_url":"https://api.github.com/repos/Bart274/home-assistant/deployments","created_at":"2016-10-19T07:10:43Z","updated_at":"2016-10-19T07:10:46Z","pushed_at":"2016-10-19T08:08:06Z","git_url":"git://github.com/Bart274/home-assistant.git","ssh_url":"git@github.com:Bart274/home-assistant.git","clone_url":"https://github.com/Bart274/home-assistant.git","svn_url":"https://github.com/Bart274/home-assistant","homepage":"https://home-assistant.io","size":41880,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"dev"}},"base":{"label":"home-assistant:dev","ref":"dev","sha":"5799d1aec9a80c0f650b7e9ec7556b59d9ab8446","user":{"login":"home-assistant","id":13844975,"avatar_url":"https://avatars.githubusercontent.com/u/13844975?v=3","gravatar_id":"","url":"https://api.github.com/users/home-assistant","html_url":"https://github.com/home-assistant","followers_url":"https://api.github.com/users/home-assistant/followers","following_url":"https://api.github.com/users/home-assistant/following{/other_user}","gists_url":"https://api.github.com/users/home-assistant/gists{/gist_id}","starred_url":"https://api.github.com/users/home-assistant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/home-assistant/subscriptions","organizations_url":"https://api.github.com/users/home-assistant/orgs","repos_url":"https://api.github.com/users/home-assistant/repos","events_url":"https://api.github.com/users/home-assistant/events{/privacy}","received_events_url":"https://api.github.com/users/home-assistant/received_events","type":"Organization","site_admin":false},"repo":{"id":12888993,"name":"home-assistant","full_name":"home-assistant/home-assistant","owner":{"login":"home-assistant","id":13844975,"avatar_url":"https://avatars.githubusercontent.com/u/13844975?v=3","gravatar_id":"","url":"https://api.github.com/users/home-assistant","html_url":"https://github.com/home-assistant","followers_url":"https://api.github.com/users/home-assistant/followers","following_url":"https://api.github.com/users/home-assistant/following{/other_user}","gists_url":"https://api.github.com/users/home-assistant/gists{/gist_id}","starred_url":"https://api.github.com/users/home-assistant/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/home-assistant/subscriptions","organizations_url":"https://api.github.com/users/home-assistant/orgs","repos_url":"https://api.github.com/users/home-assistant/repos","events_url":"https://api.github.com/users/home-assistant/events{/privacy}","received_events_url":"https://api.github.com/users/home-assistant/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/home-assistant/home-assistant","description":":house_with_garden: Open-source home automation platform running on Python 3","fork":false,"url":"https://api.github.com/repos/home-assistant/home-assistant","forks_url":"https://api.github.com/repos/home-assistant/home-assistant/forks","keys_url":"https://api.github.com/repos/home-assistant/home-assistant/keys{/key_id}","collaborators_url":"https://api.github.com/repos/home-assistant/home-assistant/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/home-assistant/home-assistant/teams","hooks_url":"https://api.github.com/repos/home-assistant/home-assistant/hooks","issue_events_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/events{/number}","events_url":"https://api.github.com/repos/home-assistant/home-assistant/events","assignees_url":"https://api.github.com/repos/home-assistant/home-assistant/assignees{/user}","branches_url":"https://api.github.com/repos/home-assistant/home-assistant/branches{/branch}","tags_url":"https://api.github.com/repos/home-assistant/home-assistant/tags","blobs_url":"https://api.github.com/repos/home-assistant/home-assistant/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/home-assistant/home-assistant/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/home-assistant/home-assistant/git/refs{/sha}","trees_url":"https://api.github.com/repos/home-assistant/home-assistant/git/trees{/sha}","statuses_url":"https://api.github.com/repos/home-assistant/home-assistant/statuses/{sha}","languages_url":"https://api.github.com/repos/home-assistant/home-assistant/languages","stargazers_url":"https://api.github.com/repos/home-assistant/home-assistant/stargazers","contributors_url":"https://api.github.com/repos/home-assistant/home-assistant/contributors","subscribers_url":"https://api.github.com/repos/home-assistant/home-assistant/subscribers","subscription_url":"https://api.github.com/repos/home-assistant/home-assistant/subscription","commits_url":"https://api.github.com/repos/home-assistant/home-assistant/commits{/sha}","git_commits_url":"https://api.github.com/repos/home-assistant/home-assistant/git/commits{/sha}","comments_url":"https://api.github.com/repos/home-assistant/home-assistant/comments{/number}","issue_comment_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/comments{/number}","contents_url":"https://api.github.com/repos/home-assistant/home-assistant/contents/{+path}","compare_url":"https://api.github.com/repos/home-assistant/home-assistant/compare/{base}...{head}","merges_url":"https://api.github.com/repos/home-assistant/home-assistant/merges","archive_url":"https://api.github.com/repos/home-assistant/home-assistant/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/home-assistant/home-assistant/downloads","issues_url":"https://api.github.com/repos/home-assistant/home-assistant/issues{/number}","pulls_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls{/number}","milestones_url":"https://api.github.com/repos/home-assistant/home-assistant/milestones{/number}","notifications_url":"https://api.github.com/repos/home-assistant/home-assistant/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/home-assistant/home-assistant/labels{/name}","releases_url":"https://api.github.com/repos/home-assistant/home-assistant/releases{/id}","deployments_url":"https://api.github.com/repos/home-assistant/home-assistant/deployments","created_at":"2013-09-17T07:29:48Z","updated_at":"2016-10-19T06:51:15Z","pushed_at":"2016-10-19T08:12:36Z","git_url":"git://github.com/home-assistant/home-assistant.git","ssh_url":"git@github.com:home-assistant/home-assistant.git","clone_url":"https://github.com/home-assistant/home-assistant.git","svn_url":"https://github.com/home-assistant/home-assistant","homepage":"https://home-assistant.io","size":83305,"stargazers_count":4365,"watchers_count":4365,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1116,"mirror_url":null,"open_issues_count":281,"forks":1116,"open_issues":281,"watchers":4365,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3946"},"html":{"href":"https://github.com/home-assistant/home-assistant/pull/3946"},"issue":{"href":"https://api.github.com/repos/home-assistant/home-assistant/issues/3946"},"comments":{"href":"https://api.github.com/repos/home-assistant/home-assistant/issues/3946/comments"},"review_comments":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3946/comments"},"review_comment":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/3946/commits"},"statuses":{"href":"https://api.github.com/repos/home-assistant/home-assistant/statuses/b849d04b1d11fdf190fa41017a204a2c195d72dc"}}}}
{"actor":{"display_login":"balloobbot"}}