{"action":"created","comment":{"url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/comments/61688722","id":61688722,"diff_hunk":"@@ -0,0 +1,160 @@\n+\"\"\"\n+homeassistant.components.garage_door.myq\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+Support for Chamberlain garage doors.\n+\n+For more details about this platform, please refer to the documentation at\n+https://home-assistant.io/components/garage_door.myq/\n+\"\"\"\n+\n+import logging\n+import requests\n+\n+from homeassistant.components.garage_door import GarageDoorDevice\n+from homeassistant.const import CONF_USERNAME, CONF_PASSWORD, CONF_NAME\n+\n+\n+REQUIREMENTS = []\n+\n+\n+def setup_platform(hass, config, add_devices, discovery_info=None):\n+    \"\"\" Sets up the MyQ garage door. \"\"\"\n+    username = config.get(CONF_USERNAME)\n+    password = config.get(CONF_PASSWORD)\n+    name = config.get(CONF_NAME) if \\\n+        CONF_NAME else \"MyQ\"  # is this the right way?\n+\n+    if username is None or password is None:\n+        logging.getLogger(__name__).error(\n+            \"Missing username or password.\")\n+        return\n+\n+    myq = MyQAPI(username, password)\n+\n+    add_devices(MyQGarageDoorDevice(myq, door, name) for door\n+                in myq.get_garage_doors())\n+\n+\n+class MyQAPI(object):\n+    # as bananas as it seems, this token is valid for all iOS app instances\n+    APP_ID = \\\n+        \"Vj8pQggXLhLy0WHahglCD4N1nAkkXQtGYpq2HrHD7H1nvmbT55KqtN6RSF4ILB%2Fi\"\n+    LOCALE = \"en\"\n+\n+    HOST_URI = \"myqexternal.myqdevice.com\"\n+    LOGIN_ENDPOINT = \"Membership/ValidateUserWithCulture\"\n+    DEVICE_LIST_ENDPOINT = \"api/UserDeviceDetails\"\n+    DEVICE_SET_ENDPOINT = \"Device/setDeviceAttribute\"\n+    DEVICE_STATUS_ENDPOINT = \"/Device/getDeviceAttribute\"\n+    DOOR_STATE = {\n+        '1': 'open',\n+        '2': 'close',\n+        '4': 'opening',\n+        '5': 'closing',\n+        '8': 'in_transition',\n+        '9': 'open'\n+    }\n+\n+    def __init__(self, username, password):\n+        self.username = username\n+        self.password = password\n+        self.security_token = None\n+        self._logged_in = False\n+\n+    def login(self):\n+        params = {\n+            'username': self.username,\n+            'password': self.password,\n+            'appId': self.APP_ID,\n+            'culture': 'en'\n+        }\n+\n+        login = requests.get(\n+            'https://{host_uri}/{login_endpoint}'.format(\n+                host_uri=self.HOST_URI,\n+                login_endpoint=self.LOGIN_ENDPOINT),\n+            params=params)\n+        auth = login.json()\n+        self.security_token = auth['SecurityToken']\n+        logging.getLogger(__name__).debug('logged in to MyQ API')\n+        return True\n+\n+    def get_devices(self):\n+        if not self._logged_in:\n+            self._logged_in = self.login()\n+        params = {\n+            'appId': self.APP_ID,\n+            'securityToken': self.security_token\n+        }\n+        devices = requests.get(\n+            'https://{host_uri}/{device_list_endpoint}'.format(\n+                host_uri=self.HOST_URI,\n+                device_list_endpoint=self.DEVICE_LIST_ENDPOINT),\n+            params=params)\n+        devices = devices.json()['Devices']\n+        return devices\n+\n+    def get_garage_doors(self):\n+        devices = self.get_devices()\n+        garage_doors = []\n+        for d in devices:\n+            if d['MyQDeviceTypeName'] == 'VGDO':\n+                for a in d['Attributes']:\n+                    if a['AttributeDisplayName'] == 'desc' and \\\n+                            a['Value'] == 'Garage Door Opener':\n+                        garage_doors.append(d['DeviceId'])\n+        return garage_doors\n+\n+    def get_status(self, device_id):\n+        params = {\n+            'appId': self.APP_ID,\n+            'securityToken': self.security_token,\n+            'devId': device_id,\n+            'name': 'doorstate',\n+        }\n+        device_status = requests.get(\n+            'https://{host_uri}/{device_status_endpoint}'.format(\n+                host_uri=self.HOST_URI,\n+                device_status_endpoint=self.DEVICE_STATUS_ENDPOINT),\n+            params=params)\n+        attval = device_status.json()['AttributeValue']\n+        garage_state = self.DOOR_STATE[attval]\n+        return garage_state\n+\n+    def set_state(self, device_id, state):","path":"homeassistant/components/garage_door/myq.py","position":124,"original_position":124,"commit_id":"c0fec98936088c23f3e6619a2d38bad3175a439b","original_commit_id":"c0fec98936088c23f3e6619a2d38bad3175a439b","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* D102: Missing docstring in public method","created_at":"2016-05-01T15:48:12Z","updated_at":"2016-05-01T15:48:12Z","html_url":"https://github.com/home-assistant/home-assistant/pull/1961#discussion_r61688722","pull_request_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/1961","_links":{"self":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/comments/61688722"},"html":{"href":"https://github.com/home-assistant/home-assistant/pull/1961#discussion_r61688722"},"pull_request":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/1961"}}},"pull_request":{"url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/1961","id":68499156,"html_url":"https://github.com/home-assistant/home-assistant/pull/1961","diff_url":"https://github.com/home-assistant/home-assistant/pull/1961.diff","patch_url":"https://github.com/home-assistant/home-assistant/pull/1961.patch","issue_url":"https://api.github.com/repos/home-assistant/home-assistant/issues/1961","number":1961,"state":"open","locked":false,"title":"MyQ Chamberlain Garage Opener","user":{"login":"maxvitek","id":3980749,"avatar_url":"https://avatars.githubusercontent.com/u/3980749?v=3","gravatar_id":"","url":"https://api.github.com/users/maxvitek","html_url":"https://github.com/maxvitek","followers_url":"https://api.github.com/users/maxvitek/followers","following_url":"https://api.github.com/users/maxvitek/following{/other_user}","gists_url":"https://api.github.com/users/maxvitek/gists{/gist_id}","starred_url":"https://api.github.com/users/maxvitek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/maxvitek/subscriptions","organizations_url":"https://api.github.com/users/maxvitek/orgs","repos_url":"https://api.github.com/users/maxvitek/repos","events_url":"https://api.github.com/users/maxvitek/events{/privacy}","received_events_url":"https://api.github.com/users/maxvitek/received_events","type":"User","site_admin":false},"body":"**Description:**  This is a component for the MyQ app-enabled Chamberlain garage door openers.  I have only one model to test with, but this code has been working well for about 6 months.\r\n\r\n\r\n**Related issue (if applicable):** #\r\n\r\n**Example entry for `configuration.yaml` (if applicable):**\r\n```yaml\r\ngarage_door:\r\n  platform: myq\r\n  name: Garage Door\r\n  username: <username>\r\n  password: <password>\r\n```\r\n\r\n**Checklist:**\r\n\r\nIf code communicates with devices:\r\n  - [x] Local tests with `tox` run successfully. **Your PR cannot be merged unless tests pass**\r\n  - [x] New dependencies have been added to the `REQUIREMENTS` variable ([example][ex-requir]).\r\n  - [x] New dependencies are only imported inside functions that use them ([example][ex-import]).\r\n  - [x] New dependencies have been added to `requirements_all.txt` by running `script/gen_requirements_all.py`.\r\n  - [x] New files were added to `.coveragerc`.\r\n\r\nIf the code does not interact with devices:\r\n  - [ ] Local tests with `tox` run successfully. **Your PR cannot be merged unless tests pass**\r\n  - [ ] Tests have been added to verify that the new code works.\r\n\r\n[fork]: http://stackoverflow.com/a/7244456\r\n[squash]: https://github.com/ginatrapani/todo.txt-android/wiki/Squash-All-Commits-Related-to-a-Single-Issue-into-a-Single-Commit\r\n[ex-requir]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard.py#L16\r\n[ex-import]: https://github.com/home-assistant/home-assistant/blob/dev/homeassistant/components/keyboard.py#L51\r\n\r\n","created_at":"2016-05-01T15:48:04Z","updated_at":"2016-05-01T15:48:12Z","closed_at":null,"merged_at":null,"merge_commit_sha":"ea329dd6caa81ee3e150ab1c21977ab93048312d","assignee":null,"milestone":null,"commits_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/1961/commits","review_comments_url":"https://api.github.com/repos/home-assistant/home-assistant/pulls/1961/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/1961/comments","statuses_url":"https://api.github.com/repos/home-assistant/home-assistant/statuses/c0fec98936088c23f3e6619a2d38bad3175a439b","head":{"label":"maxvitek:dev","ref":"dev","sha":"c0fec98936088c23f3e6619a2d38bad3175a439b","user":{"login":"maxvitek","id":3980749,"avatar_url":"https://avatars.githubusercontent.com/u/3980749?v=3","gravatar_id":"","url":"https://api.github.com/users/maxvitek","html_url":"https://github.com/maxvitek","followers_url":"https://api.github.com/users/maxvitek/followers","following_url":"https://api.github.com/users/maxvitek/following{/other_user}","gists_url":"https://api.github.com/users/maxvitek/gists{/gist_id}","starred_url":"https://api.github.com/users/maxvitek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/maxvitek/subscriptions","organizations_url":"https://api.github.com/users/maxvitek/orgs","repos_url":"https://api.github.com/users/maxvitek/repos","events_url":"https://api.github.com/users/maxvitek/events{/privacy}","received_events_url":"https://api.github.com/users/maxvitek/received_events","type":"User","site_admin":false},"repo":{"id":57465630,"name":"home-assistant","full_name":"maxvitek/home-assistant","owner":{"login":"maxvitek","id":3980749,"avatar_url":"https://avatars.githubusercontent.com/u/3980749?v=3","gravatar_id":"","url":"https://api.github.com/users/maxvitek","html_url":"https://github.com/maxvitek","followers_url":"https://api.github.com/users/maxvitek/followers","following_url":"https://api.github.com/users/maxvitek/following{/other_user}","gists_url":"https://api.github.com/users/maxvitek/gists{/gist_id}","starred_url":"https://api.github.com/users/maxvitek/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/maxvitek/subscriptions","organizations_url":"https://api.github.com/users/maxvitek/orgs","repos_url":"https://api.github.com/users/maxvitek/repos","events_url":"https://api.github.com/users/maxvitek/events{/privacy}","received_events_url":"https://api.github.com/users/maxvitek/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/maxvitek/home-assistant","description":":house_with_garden: Open-source home automation platform running on Python 3","fork":true,"url":"https://api.github.com/repos/maxvitek/home-assistant","forks_url":"https://api.github.com/repos/maxvitek/home-assistant/forks","keys_url":"https://api.github.com/repos/maxvitek/home-assistant/keys{/key_id}","collaborators_url":"https://api.github.com/repos/maxvitek/home-assistant/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/maxvitek/home-assistant/teams","hooks_url":"https://api.github.com/repos/maxvitek/home-assistant/hooks","issue_events_url":"https://api.github.com/repos/maxvitek/home-assistant/issues/events{/number}","events_url":"https://api.github.com/repos/maxvitek/home-assistant/events","assignees_url":"https://api.github.com/repos/maxvitek/home-assistant/assignees{/user}","branches_url":"https://api.github.com/repos/maxvitek/home-assistant/branches{/branch}","tags_url":"https://api.github.com/repos/maxvitek/home-assistant/tags","blobs_url":"https://api.github.com/repos/maxvitek/home-assistant/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/maxvitek/home-assistant/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/maxvitek/home-assistant/git/refs{/sha}","trees_url":"https://api.github.com/repos/maxvitek/home-assistant/git/trees{/sha}","statuses_url":"https://api.github.com/repos/maxvitek/home-assistant/statuses/{sha}","languages_url":"https://api.github.com/repos/maxvitek/home-assistant/languages","stargazers_url":"https://api.github.com/repos/maxvitek/home-assistant/stargazers","contributors_url":"https://api.github.com/repos/maxvitek/home-assistant/contributors","subscribers_url":"https://api.github.com/repos/maxvitek/home-assistant/subscribers","subscription_url":"https://api.github.com/repos/maxvitek/home-assistant/subscription","commits_url":"https://api.github.com/repos/maxvitek/home-assistant/commits{/sha}","git_commits_url":"https://api.github.com/repos/maxvitek/home-assistant/git/commits{/sha}","comments_url":"https://api.github.com/repos/maxvitek/home-assistant/comments{/number}","issue_comment_url":"https://api.github.com/repos/maxvitek/home-assistant/issues/comments{/number}","contents_url":"https://api.github.com/repos/maxvitek/home-assistant/contents/{+path}","compare_url":"https://api.github.com/repos/maxvitek/home-assistant/compare/{base}...{head}","merges_url":"https://api.github.com/repos/maxvitek/home-assistant/merges","archive_url":"https://api.github.com/repos/maxvitek/home-assistant/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/maxvitek/home-assistant/downloads","issues_url":"https://api.github.com/repos/maxvitek/home-assistant/issues{/number}","pulls_url":"https://api.github.com/repos/maxvitek/home-assistant/pulls{/number}","milestones_url":"https://api.github.com/repos/maxvitek/home-assistant/milestones{/number}","notifications_url":"https://api.github.com/repos/maxvitek/home-assistant/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/maxvitek/home-assistant/labels{/name}","releases_url":"https://api.github.com/repos/maxvitek/home-assistant/releases{/id}","deployments_url":"https://api.github.com/repos/maxvitek/home-assistant/deployments","created_at":"2016-04-30T23:09:15Z","updated_at":"2016-04-30T23:09:17Z","pushed_at":"2016-05-01T15:44:06Z","git_url":"git://github.com/maxvitek/home-assistant.git","ssh_url":"git@github.com:maxvitek/home-assistant.git","clone_url":"https://github.com/maxvitek/home-assistant.git","svn_url":"https://github.com/maxvitek/home-assistant","homepage":"https://home-assistant.io","size":57899,"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":"069a4b1706b5d4cb7be94e25c38ceb233d2a4ad5","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-05-01T07:39:49Z","pushed_at":"2016-05-01T15:48:05Z","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":65063,"stargazers_count":3267,"watchers_count":3267,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":true,"forks_count":649,"mirror_url":null,"open_issues_count":164,"forks":649,"open_issues":164,"watchers":3267,"default_branch":"dev"}},"_links":{"self":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/1961"},"html":{"href":"https://github.com/home-assistant/home-assistant/pull/1961"},"issue":{"href":"https://api.github.com/repos/home-assistant/home-assistant/issues/1961"},"comments":{"href":"https://api.github.com/repos/home-assistant/home-assistant/issues/1961/comments"},"review_comments":{"href":"https://api.github.com/repos/home-assistant/home-assistant/pulls/1961/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/1961/commits"},"statuses":{"href":"https://api.github.com/repos/home-assistant/home-assistant/statuses/c0fec98936088c23f3e6619a2d38bad3175a439b"}}}}