{"action":"created","comment":{"url":"https://api.github.com/repos/openhab/openhab2-addons/pulls/comments/134600201","pull_request_review_id":57896998,"id":134600201,"diff_hunk":"@@ -0,0 +1,145 @@\n+/**\n+ * Copyright (c) 2010-2017 by the respective copyright holders.\n+ *\n+ * All rights reserved. This program and the accompanying materials\n+ * are made available under the terms of the Eclipse Public License v1.0\n+ * which accompanies this distribution, and is available at\n+ * http://www.eclipse.org/legal/epl-v10.html\n+ */\n+package org.openhab.binding.yamahareceiver.internal.protocol.xml;\n+\n+import java.io.BufferedReader;\n+import java.io.DataOutputStream;\n+import java.io.IOException;\n+import java.io.InputStream;\n+import java.io.InputStreamReader;\n+import java.net.HttpURLConnection;\n+import java.net.URL;\n+\n+import org.openhab.binding.yamahareceiver.internal.protocol.AbstractConnection;\n+import org.slf4j.Logger;\n+import org.slf4j.LoggerFactory;\n+\n+/**\n+ * All other protocol classes in this directory use this class for communication. An object\n+ * of HttpXMLSendReceive is always bound to a specific host.\n+ *\n+ * @author David Graeff - Initial contribution\n+ *\n+ */\n+public class XMLConnection extends AbstractConnection {\n+    private Logger logger = LoggerFactory.getLogger(XMLConnection.class);\n+\n+    public final static String XML_GET = \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?><YAMAHA_AV cmd=\\\"GET\\\">\";\n+    public final static String XML_PUT = \"<?xml version=\\\"1.0\\\" encoding=\\\"utf-8\\\"?><YAMAHA_AV cmd=\\\"PUT\\\">\";\n+    public final static String XML_END = \"</YAMAHA_AV>\";\n+\n+    public XMLConnection(String host) {\n+        super(host);\n+    }\n+\n+    /**\n+     * Post the given xml message\n+     *\n+     * @param message XML formatted message excluding < ?xml > or <YAMAHA_AV> tags.\n+     * @throws IOException\n+     */\n+    @Override\n+    public void send(String message) throws IOException {\n+        HttpURLConnection connection = null;\n+        if (message.startsWith(\"<?xml\")) {\n+            throw new IOException(\"No preformatted xml allowed!\");\n+        }\n+\n+        message = XML_PUT + message + XML_END;\n+\n+        writeTraceFile(message);\n+\n+        try {\n+            URL url = new URL(\"http://\" + host + \"/YamahaRemoteControl/ctrl\");\n+            connection = (HttpURLConnection) url.openConnection();\n+            connection.setRequestMethod(\"POST\");\n+            connection.setRequestProperty(\"Content-Length\", \"\" + Integer.toString(message.length()));\n+\n+            connection.setUseCaches(false);\n+            connection.setDoInput(true);\n+            connection.setDoOutput(true);\n+\n+            // Send request\n+            DataOutputStream wr = new DataOutputStream(connection.getOutputStream());\n+            wr.writeBytes(message);\n+            wr.flush();\n+            wr.close();\n+\n+            if (connection.getResponseCode() != 200) {\n+                throw new IOException(\"Changing a value on the Yamaha AVR failed: \" + message);\n+            }\n+\n+        } catch (IOException e) {\n+            throw e;\n+        } finally {\n+            if (connection != null) {\n+                connection.disconnect();\n+            }\n+        }\n+    }\n+\n+    /**\n+     * Post the given xml message and return the response as string.\n+     *\n+     * @param message XML formatted message excluding <?xml> or <YAMAHA_AV> tags.\n+     * @return Return the response as text or throws an exception if the connection failed.\n+     * @throws IOException\n+     */\n+    @Override\n+    public String sendReceive(String message) throws IOException {\n+        HttpURLConnection connection = null;\n+        if (message.startsWith(\"<?xml\")) {\n+            throw new IOException(\"No preformatted xml allowed!\");\n+        }\n+\n+        message = XML_GET + message + XML_END;\n+\n+        writeTraceFile(message);\n+\n+        try {\n+            URL url = new URL(\"http://\" + host + \"/YamahaRemoteControl/ctrl\");","path":"addons/binding/org.openhab.binding.yamahareceiver/src/main/java/org/openhab/binding/yamahareceiver/internal/protocol/xml/XMLConnection.java","position":59,"original_position":106,"commit_id":"71c940015a4ccccb93bf8b66037488f5b58282dd","original_commit_id":"71c940015a4ccccb93bf8b66037488f5b58282dd","user":{"login":"martinvw","id":2625279,"avatar_url":"https://avatars3.githubusercontent.com/u/2625279?v=4","gravatar_id":"","url":"https://api.github.com/users/martinvw","html_url":"https://github.com/martinvw","followers_url":"https://api.github.com/users/martinvw/followers","following_url":"https://api.github.com/users/martinvw/following{/other_user}","gists_url":"https://api.github.com/users/martinvw/gists{/gist_id}","starred_url":"https://api.github.com/users/martinvw/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/martinvw/subscriptions","organizations_url":"https://api.github.com/users/martinvw/orgs","repos_url":"https://api.github.com/users/martinvw/repos","events_url":"https://api.github.com/users/martinvw/events{/privacy}","received_events_url":"https://api.github.com/users/martinvw/received_events","type":"User","site_admin":false},"body":"Also in this case, see above","created_at":"2017-08-22T20:59:22Z","updated_at":"2017-08-22T21:01:26Z","html_url":"https://github.com/openhab/openhab2-addons/pull/2558#discussion_r134600201","pull_request_url":"https://api.github.com/repos/openhab/openhab2-addons/pulls/2558","_links":{"self":{"href":"https://api.github.com/repos/openhab/openhab2-addons/pulls/comments/134600201"},"html":{"href":"https://github.com/openhab/openhab2-addons/pull/2558#discussion_r134600201"},"pull_request":{"href":"https://api.github.com/repos/openhab/openhab2-addons/pulls/2558"}}},"pull_request":{"url":"https://api.github.com/repos/openhab/openhab2-addons/pulls/2558","id":135693115,"html_url":"https://github.com/openhab/openhab2-addons/pull/2558","diff_url":"https://github.com/openhab/openhab2-addons/pull/2558.diff","patch_url":"https://github.com/openhab/openhab2-addons/pull/2558.patch","issue_url":"https://api.github.com/repos/openhab/openhab2-addons/issues/2558","number":2558,"state":"open","locked":false,"title":"[Yamaha] Tuner band selection and preset feature for dual band models (RX-S601D) and Prepare for json protocol addition","user":{"login":"zarusz","id":2655886,"avatar_url":"https://avatars0.githubusercontent.com/u/2655886?v=4","gravatar_id":"","url":"https://api.github.com/users/zarusz","html_url":"https://github.com/zarusz","followers_url":"https://api.github.com/users/zarusz/followers","following_url":"https://api.github.com/users/zarusz/following{/other_user}","gists_url":"https://api.github.com/users/zarusz/gists{/gist_id}","starred_url":"https://api.github.com/users/zarusz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zarusz/subscriptions","organizations_url":"https://api.github.com/users/zarusz/orgs","repos_url":"https://api.github.com/users/zarusz/repos","events_url":"https://api.github.com/users/zarusz/events{/privacy}","received_events_url":"https://api.github.com/users/zarusz/received_events","type":"User","site_admin":false},"body":"This PR entails two parts:\r\n\r\n**Tuner band selection and preset feature for dual band models (RX-S601D)**\r\n\r\nThis commit solves issues with the Tuner/DAB compatibility described in #2524 for the Yamaha binding.\r\nThis **depends on** #2533.\r\n\r\n**Description**\r\nThe Yamaha Receiver RX-S601D comes with a digital and analog tuner that supports two band modes FM and DAB+. The changes add support and fixes for this model:\r\n* Added channel to change the tuner band (FM vs. DAB+)\r\n* Fixed the preset channel which on RX-S601D requires band information\r\n* Fixed the song/album/title/station channels which on RX-S601D requires band information.\r\n* Fixed the playback to be always disabling when input is Tuner and DAB device.\r\n* Adds device feature detection for backward compatibility - for older tuner that are not dual band the binding will work in the same way\r\n\r\n**Testing**\r\nTested with:\r\n- Yamaha Receiver RX-S601D\r\n- Latest OpenHAB 2.2.0-SNAPSHOT\r\n- Raspbian Jessie\r\n\r\nMaven built JAR on [my DropBox](https://www.dropbox.com/sh/pa069i3bnbsptzj/AABqgJSrQ0lISfDNkUCbwWUma?dl=0).\r\n\r\n**Certificate of Origin**\r\nSigned-off-by: Tomasz Maruszak <maruszaktomasz@gmail.com> (https://github.com/zarusz)\r\n\r\n-----\r\n\r\n**Prepare for json protocol addition**\r\n\r\nThis commit does not add any functionality. This commit depends on #2525.\r\n\r\nRemove old ControlFlow and Class diagram pictures, they are outdated now.\r\nMove constants from all over the code to YamahaReceiverBindingConstants class.\r\nMove states out of protocol communication classes. States are POJO + invalidate() method and live in the state package.\r\nMove communication classes to protocol/xml package and extract protocol interfaces.\r\nProtocol interfaces are in the protocol package now.\r\nRefactor HttpXMLSendReceive to AbstractConnection and XMLConnection implementation.\r\nCreate factory class in protocol package.\r\nThis prepares the code for a new protocol/json package and a JSONConnection implementation. The new protocol is called Yamaha Extended Control protocol (YXC) and is exclusively used on all AVRs produced later than 2013 (MusicCast enabled products). The basic protocol is similar to the old XML one. The advanced functionality includes DLNA based audio streaming.\r\n\r\nSpecification\r\n\r\nhttps://github.com/neutmute/swimbait/tree/master/doc/yamaha\r\nhttps://hexdocs.pm/musiccast/api-reference.html\r\nOther implementations\r\n\r\nhttps://github.com/foxthefox/yamaha-yxc-nodejs (Node JS)\r\nhttps://github.com/onkelrico/yxc-client (Java)\r\nhttps://community.home-assistant.io/t/support-for-new-yamaha-receivers-and-musiccast-devices/17001 (Python / Home Assistant)\r\n\r\nSigned-off-by: David Gräff david.graeff@web.de","created_at":"2017-08-14T21:38:20Z","updated_at":"2017-08-22T21:01:26Z","closed_at":null,"merged_at":null,"merge_commit_sha":"6ee3885cd5e46fb93ca37c90e555950aacd5f3cc","assignee":null,"assignees":[],"requested_reviewers":[],"milestone":null,"commits_url":"https://api.github.com/repos/openhab/openhab2-addons/pulls/2558/commits","review_comments_url":"https://api.github.com/repos/openhab/openhab2-addons/pulls/2558/comments","review_comment_url":"https://api.github.com/repos/openhab/openhab2-addons/pulls/comments{/number}","comments_url":"https://api.github.com/repos/openhab/openhab2-addons/issues/2558/comments","statuses_url":"https://api.github.com/repos/openhab/openhab2-addons/statuses/71c940015a4ccccb93bf8b66037488f5b58282dd","head":{"label":"zarusz:2524_yamaha_tuner_band","ref":"2524_yamaha_tuner_band","sha":"71c940015a4ccccb93bf8b66037488f5b58282dd","user":{"login":"zarusz","id":2655886,"avatar_url":"https://avatars0.githubusercontent.com/u/2655886?v=4","gravatar_id":"","url":"https://api.github.com/users/zarusz","html_url":"https://github.com/zarusz","followers_url":"https://api.github.com/users/zarusz/followers","following_url":"https://api.github.com/users/zarusz/following{/other_user}","gists_url":"https://api.github.com/users/zarusz/gists{/gist_id}","starred_url":"https://api.github.com/users/zarusz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zarusz/subscriptions","organizations_url":"https://api.github.com/users/zarusz/orgs","repos_url":"https://api.github.com/users/zarusz/repos","events_url":"https://api.github.com/users/zarusz/events{/privacy}","received_events_url":"https://api.github.com/users/zarusz/received_events","type":"User","site_admin":false},"repo":{"id":99510647,"name":"openhab2-addons","full_name":"zarusz/openhab2-addons","owner":{"login":"zarusz","id":2655886,"avatar_url":"https://avatars0.githubusercontent.com/u/2655886?v=4","gravatar_id":"","url":"https://api.github.com/users/zarusz","html_url":"https://github.com/zarusz","followers_url":"https://api.github.com/users/zarusz/followers","following_url":"https://api.github.com/users/zarusz/following{/other_user}","gists_url":"https://api.github.com/users/zarusz/gists{/gist_id}","starred_url":"https://api.github.com/users/zarusz/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/zarusz/subscriptions","organizations_url":"https://api.github.com/users/zarusz/orgs","repos_url":"https://api.github.com/users/zarusz/repos","events_url":"https://api.github.com/users/zarusz/events{/privacy}","received_events_url":"https://api.github.com/users/zarusz/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/zarusz/openhab2-addons","description":"Add-ons for openHAB 2.x","fork":true,"url":"https://api.github.com/repos/zarusz/openhab2-addons","forks_url":"https://api.github.com/repos/zarusz/openhab2-addons/forks","keys_url":"https://api.github.com/repos/zarusz/openhab2-addons/keys{/key_id}","collaborators_url":"https://api.github.com/repos/zarusz/openhab2-addons/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/zarusz/openhab2-addons/teams","hooks_url":"https://api.github.com/repos/zarusz/openhab2-addons/hooks","issue_events_url":"https://api.github.com/repos/zarusz/openhab2-addons/issues/events{/number}","events_url":"https://api.github.com/repos/zarusz/openhab2-addons/events","assignees_url":"https://api.github.com/repos/zarusz/openhab2-addons/assignees{/user}","branches_url":"https://api.github.com/repos/zarusz/openhab2-addons/branches{/branch}","tags_url":"https://api.github.com/repos/zarusz/openhab2-addons/tags","blobs_url":"https://api.github.com/repos/zarusz/openhab2-addons/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/zarusz/openhab2-addons/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/zarusz/openhab2-addons/git/refs{/sha}","trees_url":"https://api.github.com/repos/zarusz/openhab2-addons/git/trees{/sha}","statuses_url":"https://api.github.com/repos/zarusz/openhab2-addons/statuses/{sha}","languages_url":"https://api.github.com/repos/zarusz/openhab2-addons/languages","stargazers_url":"https://api.github.com/repos/zarusz/openhab2-addons/stargazers","contributors_url":"https://api.github.com/repos/zarusz/openhab2-addons/contributors","subscribers_url":"https://api.github.com/repos/zarusz/openhab2-addons/subscribers","subscription_url":"https://api.github.com/repos/zarusz/openhab2-addons/subscription","commits_url":"https://api.github.com/repos/zarusz/openhab2-addons/commits{/sha}","git_commits_url":"https://api.github.com/repos/zarusz/openhab2-addons/git/commits{/sha}","comments_url":"https://api.github.com/repos/zarusz/openhab2-addons/comments{/number}","issue_comment_url":"https://api.github.com/repos/zarusz/openhab2-addons/issues/comments{/number}","contents_url":"https://api.github.com/repos/zarusz/openhab2-addons/contents/{+path}","compare_url":"https://api.github.com/repos/zarusz/openhab2-addons/compare/{base}...{head}","merges_url":"https://api.github.com/repos/zarusz/openhab2-addons/merges","archive_url":"https://api.github.com/repos/zarusz/openhab2-addons/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/zarusz/openhab2-addons/downloads","issues_url":"https://api.github.com/repos/zarusz/openhab2-addons/issues{/number}","pulls_url":"https://api.github.com/repos/zarusz/openhab2-addons/pulls{/number}","milestones_url":"https://api.github.com/repos/zarusz/openhab2-addons/milestones{/number}","notifications_url":"https://api.github.com/repos/zarusz/openhab2-addons/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/zarusz/openhab2-addons/labels{/name}","releases_url":"https://api.github.com/repos/zarusz/openhab2-addons/releases{/id}","deployments_url":"https://api.github.com/repos/zarusz/openhab2-addons/deployments","created_at":"2017-08-06T20:08:05Z","updated_at":"2017-08-06T20:08:13Z","pushed_at":"2017-08-21T18:18:49Z","git_url":"git://github.com/zarusz/openhab2-addons.git","ssh_url":"git@github.com:zarusz/openhab2-addons.git","clone_url":"https://github.com/zarusz/openhab2-addons.git","svn_url":"https://github.com/zarusz/openhab2-addons","homepage":"","size":258124,"stargazers_count":0,"watchers_count":0,"language":"Java","has_issues":false,"has_projects":true,"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":"master"}},"base":{"label":"openhab:master","ref":"master","sha":"19b2dc291c8b44c75928e6da9debb9b6a767f7db","user":{"login":"openhab","id":1007353,"avatar_url":"https://avatars0.githubusercontent.com/u/1007353?v=4","gravatar_id":"","url":"https://api.github.com/users/openhab","html_url":"https://github.com/openhab","followers_url":"https://api.github.com/users/openhab/followers","following_url":"https://api.github.com/users/openhab/following{/other_user}","gists_url":"https://api.github.com/users/openhab/gists{/gist_id}","starred_url":"https://api.github.com/users/openhab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openhab/subscriptions","organizations_url":"https://api.github.com/users/openhab/orgs","repos_url":"https://api.github.com/users/openhab/repos","events_url":"https://api.github.com/users/openhab/events{/privacy}","received_events_url":"https://api.github.com/users/openhab/received_events","type":"Organization","site_admin":false},"repo":{"id":19753195,"name":"openhab2-addons","full_name":"openhab/openhab2-addons","owner":{"login":"openhab","id":1007353,"avatar_url":"https://avatars0.githubusercontent.com/u/1007353?v=4","gravatar_id":"","url":"https://api.github.com/users/openhab","html_url":"https://github.com/openhab","followers_url":"https://api.github.com/users/openhab/followers","following_url":"https://api.github.com/users/openhab/following{/other_user}","gists_url":"https://api.github.com/users/openhab/gists{/gist_id}","starred_url":"https://api.github.com/users/openhab/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/openhab/subscriptions","organizations_url":"https://api.github.com/users/openhab/orgs","repos_url":"https://api.github.com/users/openhab/repos","events_url":"https://api.github.com/users/openhab/events{/privacy}","received_events_url":"https://api.github.com/users/openhab/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/openhab/openhab2-addons","description":"Add-ons for openHAB 2.x","fork":false,"url":"https://api.github.com/repos/openhab/openhab2-addons","forks_url":"https://api.github.com/repos/openhab/openhab2-addons/forks","keys_url":"https://api.github.com/repos/openhab/openhab2-addons/keys{/key_id}","collaborators_url":"https://api.github.com/repos/openhab/openhab2-addons/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/openhab/openhab2-addons/teams","hooks_url":"https://api.github.com/repos/openhab/openhab2-addons/hooks","issue_events_url":"https://api.github.com/repos/openhab/openhab2-addons/issues/events{/number}","events_url":"https://api.github.com/repos/openhab/openhab2-addons/events","assignees_url":"https://api.github.com/repos/openhab/openhab2-addons/assignees{/user}","branches_url":"https://api.github.com/repos/openhab/openhab2-addons/branches{/branch}","tags_url":"https://api.github.com/repos/openhab/openhab2-addons/tags","blobs_url":"https://api.github.com/repos/openhab/openhab2-addons/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/openhab/openhab2-addons/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/openhab/openhab2-addons/git/refs{/sha}","trees_url":"https://api.github.com/repos/openhab/openhab2-addons/git/trees{/sha}","statuses_url":"https://api.github.com/repos/openhab/openhab2-addons/statuses/{sha}","languages_url":"https://api.github.com/repos/openhab/openhab2-addons/languages","stargazers_url":"https://api.github.com/repos/openhab/openhab2-addons/stargazers","contributors_url":"https://api.github.com/repos/openhab/openhab2-addons/contributors","subscribers_url":"https://api.github.com/repos/openhab/openhab2-addons/subscribers","subscription_url":"https://api.github.com/repos/openhab/openhab2-addons/subscription","commits_url":"https://api.github.com/repos/openhab/openhab2-addons/commits{/sha}","git_commits_url":"https://api.github.com/repos/openhab/openhab2-addons/git/commits{/sha}","comments_url":"https://api.github.com/repos/openhab/openhab2-addons/comments{/number}","issue_comment_url":"https://api.github.com/repos/openhab/openhab2-addons/issues/comments{/number}","contents_url":"https://api.github.com/repos/openhab/openhab2-addons/contents/{+path}","compare_url":"https://api.github.com/repos/openhab/openhab2-addons/compare/{base}...{head}","merges_url":"https://api.github.com/repos/openhab/openhab2-addons/merges","archive_url":"https://api.github.com/repos/openhab/openhab2-addons/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/openhab/openhab2-addons/downloads","issues_url":"https://api.github.com/repos/openhab/openhab2-addons/issues{/number}","pulls_url":"https://api.github.com/repos/openhab/openhab2-addons/pulls{/number}","milestones_url":"https://api.github.com/repos/openhab/openhab2-addons/milestones{/number}","notifications_url":"https://api.github.com/repos/openhab/openhab2-addons/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/openhab/openhab2-addons/labels{/name}","releases_url":"https://api.github.com/repos/openhab/openhab2-addons/releases{/id}","deployments_url":"https://api.github.com/repos/openhab/openhab2-addons/deployments","created_at":"2014-05-13T19:41:58Z","updated_at":"2017-08-18T08:00:10Z","pushed_at":"2017-08-22T20:58:19Z","git_url":"git://github.com/openhab/openhab2-addons.git","ssh_url":"git@github.com:openhab/openhab2-addons.git","clone_url":"https://github.com/openhab/openhab2-addons.git","svn_url":"https://github.com/openhab/openhab2-addons","homepage":"","size":258440,"stargazers_count":631,"watchers_count":631,"language":"Java","has_issues":true,"has_projects":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":1094,"mirror_url":null,"open_issues_count":334,"forks":1094,"open_issues":334,"watchers":631,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/openhab/openhab2-addons/pulls/2558"},"html":{"href":"https://github.com/openhab/openhab2-addons/pull/2558"},"issue":{"href":"https://api.github.com/repos/openhab/openhab2-addons/issues/2558"},"comments":{"href":"https://api.github.com/repos/openhab/openhab2-addons/issues/2558/comments"},"review_comments":{"href":"https://api.github.com/repos/openhab/openhab2-addons/pulls/2558/comments"},"review_comment":{"href":"https://api.github.com/repos/openhab/openhab2-addons/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/openhab/openhab2-addons/pulls/2558/commits"},"statuses":{"href":"https://api.github.com/repos/openhab/openhab2-addons/statuses/71c940015a4ccccb93bf8b66037488f5b58282dd"}}}}
{"actor":{"display_login":"martinvw"}}