This repository was archived by the owner on May 17, 2021. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
some changes to XBMC binding #4622
Merged
Merged
Changes from all commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -35,7 +35,7 @@ | |
| * | ||
| * XBMC JSON RPC API: http://wiki.xbmc.org/?title=JSON-RPC_API | ||
| * | ||
| * @author tlan, Ben Jones | ||
| * @author tlan, Ben Jones, Plebs | ||
| * @since 1.5.0 | ||
| */ | ||
| public abstract class RpcCall { | ||
|
|
@@ -131,11 +131,14 @@ private void postRequest(Map<String, Object> request, Runnable completeHandler) | |
| try { | ||
| // we fire this request off asynchronously and let the completeHandler | ||
| // process any response as necessary (can be null) | ||
| ListenableFuture<Response> future = client.preparePost(uri).setBody(writeJson(request)) | ||
| String resultWrite = writeJson(request); | ||
| logger.debug("Write JSON: {}", resultWrite ); // Stefano: logging the JSON request | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please put the code through the Eclipse IDE formatter so future changes don't reformat lines with incorrect formatting. |
||
| ListenableFuture<Response> future = client.preparePost(uri).setBody(resultWrite) | ||
| .setHeader("content-type", "application/json").setHeader("accept", "application/json") | ||
| .execute(new AsyncCompletionHandler<Response>() { | ||
| @Override | ||
| public Response onCompleted(Response response) throws Exception { | ||
| logger.debug("Read JSON: {}", response.getResponseBody()); // Stefano: logging the JSON response | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please put the code through the Eclipse IDE formatter so future changes don't reformat lines with incorrect formatting. |
||
| Map<String, Object> json = readJson(response.getResponseBody()); | ||
|
|
||
| // if we get an error then throw an exception to stop the | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -33,6 +33,8 @@ | |
| import org.openhab.binding.xbmc.rpc.calls.PVRGetChannels; | ||
| import org.openhab.binding.xbmc.rpc.calls.PlayerGetActivePlayers; | ||
| import org.openhab.binding.xbmc.rpc.calls.PlayerGetItem; | ||
| import org.openhab.binding.xbmc.rpc.calls.PlayerGetLabels; | ||
| import org.openhab.binding.xbmc.rpc.calls.PlayerGetProperties; | ||
| import org.openhab.binding.xbmc.rpc.calls.PlayerOpen; | ||
| import org.openhab.binding.xbmc.rpc.calls.PlayerPlayPause; | ||
| import org.openhab.binding.xbmc.rpc.calls.PlayerStop; | ||
|
|
@@ -61,7 +63,7 @@ | |
| /** | ||
| * Manages the web socket connection for a single XBMC instance. | ||
| * | ||
| * @author tlan, Ben Jones, Ard van der Leeuw | ||
| * @author tlan, Ben Jones, Ard van der Leeuw, Plebs | ||
| * @since 1.5.0 | ||
| */ | ||
| public class XbmcConnector { | ||
|
|
@@ -125,7 +127,7 @@ public XbmcConnector(XbmcHost xbmc, EventPublisher eventPublisher) { | |
|
|
||
| /*** | ||
| * Check if the connection to the XBMC instance is active | ||
| * | ||
| * | ||
| * @return true if an active connection to the XBMC instance exists, false otherwise | ||
| */ | ||
| public boolean isConnected() { | ||
|
|
@@ -139,7 +141,7 @@ public boolean isConnected() { | |
| /** | ||
| * Attempts to create a connection to the XBMC host and begin listening | ||
| * for updates over the async http web socket | ||
| * | ||
| * | ||
| * @throws ExecutionException | ||
| * @throws InterruptedException | ||
| * @throws IOException | ||
|
|
@@ -276,15 +278,16 @@ public void run() { | |
|
|
||
| /** | ||
| * Create a mapping between an item and an xbmc property | ||
| * | ||
| * | ||
| * @param itemName | ||
| * The name of the item which should receive updates | ||
| * @param property | ||
| * The property of this xbmc instance, which is to be | ||
| * watched for changes | ||
| * | ||
| * | ||
| */ | ||
| public void addItem(String itemName, String property) { | ||
| logger.debug("Mapping: itemname = {} & property = {}", itemName, property); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please put the code through the Eclipse IDE formatter so future changes don't reformat lines with incorrect formatting. |
||
| if (!watches.containsKey(itemName)) { | ||
| watches.put(itemName, property); | ||
| } | ||
|
|
@@ -307,7 +310,7 @@ public void updatePlayerStatus() { | |
|
|
||
| /** | ||
| * Update the status of the current player | ||
| * | ||
| * | ||
| * @param updatePolledPropertiesOnly | ||
| * If updatePolledPropertiesOnly is true, only update the Player properties that need to be polled | ||
| * If updatePolledPropertiesOnly is false, update the Player state itself as well | ||
|
|
@@ -543,7 +546,7 @@ public void run() { | |
|
|
||
| /** | ||
| * Request an update for the Player properties from XBMC | ||
| * | ||
| * | ||
| * @param playerId | ||
| * The id of the currently active player | ||
| */ | ||
|
|
@@ -553,7 +556,7 @@ private void requestPlayerUpdate(int playerId) { | |
|
|
||
| /** | ||
| * Request an update for the Player properties from XBMC | ||
| * | ||
| * | ||
| * @param playerId | ||
| * The id of the currently active player | ||
| * @param updatePolledPropertiesOnly | ||
|
|
@@ -581,25 +584,78 @@ private void requestPlayerUpdate(int playerId, boolean updatePolledPropertiesOnl | |
| if (!properties.isEmpty()) { | ||
| logger.debug("[{}]: Retrieving properties ({}) for playerId {}", xbmc.getHostname(), properties.size(), | ||
| playerId); | ||
| // make the request for the player item details | ||
| final PlayerGetItem item = new PlayerGetItem(client, httpUri); | ||
| item.setPlayerId(playerId); | ||
| item.setProperties(properties); | ||
|
|
||
| item.execute(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| // now update each of the openHAB items for each property | ||
| for (String property : properties) { | ||
| String value = item.getPropertyValue(property); | ||
| if (property.equals("Player.Fanart")) { | ||
| updateFanartUrl(property, value); | ||
| } else { | ||
| final List<String> propertiesInfo = new ArrayList<String>(); | ||
| final List<String> propertiesProperties = new ArrayList<String>(); | ||
| final List<String> propertiesLabels = new ArrayList<String>(); | ||
|
|
||
| for (String property : properties) { | ||
| if (property.startsWith("Player.")) { | ||
| propertiesInfo.add(property); | ||
| } | ||
| if (property.startsWith("Property.")) { | ||
| propertiesProperties.add(property); | ||
| } | ||
| if (property.startsWith("Label.")) { | ||
| propertiesLabels.add(property); | ||
| } | ||
| } | ||
|
|
||
| // make the request for the player item details using GETINFO | ||
| if (!propertiesInfo.isEmpty()) { | ||
| final PlayerGetItem item = new PlayerGetItem(client, httpUri); | ||
| item.setPlayerId(playerId); | ||
| item.setProperties(propertiesInfo); | ||
|
|
||
| item.execute(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| // now update each of the openHAB items for each property | ||
| for (String property : propertiesInfo) { | ||
| String value = item.getPropertyValue(property); | ||
| if (property.equals("Player.Fanart")) { | ||
| updateFanartUrl(property, value); | ||
| } else { | ||
| updateProperty(property, value); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| } | ||
|
|
||
| // make the request for the player item2 details using GETPROPERTIES | ||
| if (!propertiesProperties.isEmpty()) { | ||
| final PlayerGetProperties item2 = new PlayerGetProperties(client, httpUri); | ||
| item2.setPlayerId(playerId); | ||
| item2.setProperties(propertiesProperties); | ||
|
|
||
| item2.execute(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| // now update each of the openHAB items for each property | ||
| for (String property : propertiesProperties) { | ||
| String value = item2.getPropertyValue(property); | ||
| updateProperty(property, value); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| }); | ||
| } | ||
|
|
||
| // make the request for the player item3 details using GETLABELS | ||
| if (!propertiesLabels.isEmpty()) { | ||
| final PlayerGetLabels item3 = new PlayerGetLabels(client, httpUri); | ||
| item3.setProperties(propertiesLabels); | ||
|
|
||
| item3.execute(new Runnable() { | ||
| @Override | ||
| public void run() { | ||
| // now update each of the openHAB items for each property | ||
| for (String property : propertiesLabels) { | ||
| String value = item3.getPropertyValue(property); | ||
| updateProperty(property, value); | ||
| } | ||
| } | ||
| }); | ||
| } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -652,7 +708,7 @@ private void updateProperty(String property, OnOffType value) { | |
|
|
||
| /** | ||
| * get a distinct list of player properties we have items configured for | ||
| * | ||
| * | ||
| * @return | ||
| * A list of property names | ||
| */ | ||
|
|
@@ -662,7 +718,7 @@ private List<String> getPlayerProperties() { | |
|
|
||
| /** | ||
| * get a distinct list of player properties we have items configured for | ||
| * | ||
| * | ||
| * @param updatePolledPropertiesOnly | ||
| * Only get the properties that need to be refreshed by polling if true, | ||
| * otherwise get all the properties that have items configured for | ||
|
|
@@ -676,25 +732,37 @@ private List<String> getPlayerProperties(boolean updatePolledPropertiesOnly) { | |
| for (String property : watches.values()) { | ||
| if (properties.contains(property)) { | ||
| continue; | ||
| } else if (property.equals("Player.Label")) { | ||
| } | ||
| if (property.equals("Player.State")) { | ||
| continue; | ||
| } | ||
| if (property.startsWith("Player.")) { | ||
| properties.add(property); | ||
| } else if (property.equals("Player.Title")) { | ||
| } | ||
| if (property.startsWith("Property.")) { | ||
| properties.add(property); | ||
| } | ||
| if (property.startsWith("Label.")) { | ||
| properties.add(property); | ||
| } | ||
| } | ||
| } else { | ||
| for (String property : watches.values()) { | ||
| if (!property.startsWith("Player.")) { | ||
| if (properties.contains(property)) { | ||
| continue; | ||
| } | ||
| if (property.equals("Player.State")) { | ||
| continue; | ||
| } | ||
| if (properties.contains(property)) { | ||
| continue; | ||
| if (property.startsWith("Player.")) { | ||
| properties.add(property); | ||
| } | ||
| if (property.startsWith("Property.")) { | ||
| properties.add(property); | ||
| } | ||
| if (property.startsWith("Label.")) { | ||
| properties.add(property); | ||
| } | ||
|
|
||
| properties.add(property); | ||
| } | ||
| } | ||
| return properties; | ||
|
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you certain that it is threadsafe to do this? The
execute()method is called at some refreshInterval in another thread, so it may be possible that this method could be run from each thread overlapping. You might consider using a technique like in the HTTP or Ecobee binding, where the execute() method is called based on a shortgranularity(five seconds, for example), but checks a future timestamp to see if it should do anything. The "Refresh" action would then just expire the future timestamp, so the next scheduledexecutehappens on averagegranulary/2into the future. Theexecute()method would just set the future timestamp to the current timestamp + refreshInterval. (There are certainly other sound approaches to avoiding thread safety issues.)