From db74b96fb4d47bf381bc32b1ba1ccd25fde56c25 Mon Sep 17 00:00:00 2001 From: John Cocula Date: Fri, 17 Jul 2015 17:37:15 +0100 Subject: [PATCH] Suppress occasionally failing update echo cancellations. --- .../binding/nest/internal/NestBinding.java | 94 ++++++++++++------- 1 file changed, 61 insertions(+), 33 deletions(-) diff --git a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestBinding.java b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestBinding.java index 5609894c687..949f5b07c21 100644 --- a/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestBinding.java +++ b/bundles/binding/org.openhab.binding.nest/src/main/java/org/openhab/binding/nest/internal/NestBinding.java @@ -77,7 +77,32 @@ public class NestBinding extends AbstractActiveBinding impl /** * used to store events that we have sent ourselves; we need to remember them for not reacting to them */ - private List ignoreEventList = Collections.synchronizedList(new ArrayList()); + private static class Update { + private String itemName; + private State state; + + Update(final String itemName, final State state) { + this.itemName = itemName; + this.state = state; + } + + @Override + public boolean equals(Object o) { + if (o == null || !(o instanceof Update)) { + return false; + } + return (this.itemName == null ? ((Update) o).itemName == null : this.itemName.equals(((Update) o).itemName)) + && (this.state == null ? ((Update) o).state == null : this.state.equals(((Update) o).state)); + } + + @Override + public int hashCode() { + return (this.itemName == null ? 0 : this.itemName.hashCode()) + ^ (this.state == null ? 0 : this.state.hashCode()); + } + } + + private List ignoreEventList = Collections.synchronizedList(new ArrayList()); /** * The most recently received data model, or null if none have been retrieved yet. @@ -178,8 +203,9 @@ private void readNest(OAuthCredentials oauthCredentials) throws Exception { * we need to make sure that we won't send out this event to Nest again, when receiving it on the * openHAB bus */ - ignoreEventList.add(itemName + newState.toString()); - logger.trace("Added event (item='{}', newState='{}') to the ignore event list", itemName, newState); + ignoreEventList.add(new Update(itemName, newState)); + logger.trace("Added event (item='{}', newState='{}') to the ignore event list (size={})", + itemName, newState, ignoreEventList.size()); this.eventPublisher.postUpdate(itemName, newState); } } @@ -283,8 +309,7 @@ private void commandNest(final String itemName, final Command command) { } private boolean isEcho(String itemName, State state) { - String ignoreEventListKey = itemName + state.toString(); - if (ignoreEventList.remove(ignoreEventListKey)) { + if (ignoreEventList.remove(new Update(itemName, state))) { logger.debug( "We received this event (item='{}', state='{}') from Nest, so we don't send it back again -> ignore!", itemName, state); @@ -316,44 +341,47 @@ private void updateNest(final String itemName, final State newState) { if (provider == null) { logger.warn("no matching binding provider found [itemName={}, newState={}]", itemName, newState); return; - } else { + } - try { - logger.debug("About to set property '{}' to '{}'", property, newState); + if (!provider.isOutBound(itemName)) { + logger.warn("attempt to update non-outbound item skipped [itemName={}, newState={}]", itemName, newState); + return; + } - // Ask the old DataModel to generate a new DataModel that only contains the update we want to send - DataModel updateDataModel = oldDataModel.updateDataModel(property, newState); + try { + logger.debug("About to set property '{}' to '{}'", property, newState); - logger.trace("Data model for update: {}", updateDataModel); + // Ask the old DataModel to generate a new DataModel that only contains the update we want to send + DataModel updateDataModel = oldDataModel.updateDataModel(property, newState); - if (updateDataModel == null) { - return; - } + logger.trace("Data model for update: {}", updateDataModel); - OAuthCredentials oauthCredentials = getOAuthCredentials(DEFAULT_USER_ID); + if (updateDataModel == null) { + return; + } - if (oauthCredentials == null) { - logger.warn("Unable to locate credentials for item {}; aborting update.", itemName); - return; - } + OAuthCredentials oauthCredentials = getOAuthCredentials(DEFAULT_USER_ID); - // If we don't have an access token yet, retrieve one. - if (oauthCredentials.noAccessToken()) { - if (!oauthCredentials.retrieveAccessToken()) { - logger.warn("Sending update skipped."); - return; - } - } + if (oauthCredentials == null) { + logger.warn("Unable to locate credentials for item {}; aborting update.", itemName); + return; + } - UpdateDataModelRequest request = new UpdateDataModelRequest(oauthCredentials.accessToken, - updateDataModel); - DataModelResponse response = request.execute(); - if (response.isError()) { - logger.error("Error updating data model: {}", response); + // If we don't have an access token yet, retrieve one. + if (oauthCredentials.noAccessToken()) { + if (!oauthCredentials.retrieveAccessToken()) { + logger.warn("Sending update skipped."); + return; } - } catch (Exception e) { - logger.error("Unable to update data model", e); } + + UpdateDataModelRequest request = new UpdateDataModelRequest(oauthCredentials.accessToken, updateDataModel); + DataModelResponse response = request.execute(); + if (response.isError()) { + logger.error("Error updating data model: {}", response); + } + } catch (Exception e) { + logger.error("Unable to update data model", e); } }